@tscircuit/capacity-autorouter 0.0.310 → 0.0.311

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var t=Object.create,e=Object.defineProperty,n=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.getPrototypeOf,i=Object.prototype.hasOwnProperty,r=(t,e)=>function(){return e||(0,t[s(t)[0]])((e={exports:{}}).exports,e),e.exports},a=(r,a,c)=>(c=null!=r?t(o(r)):{},((t,o,r,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of s(o))i.call(t,c)||c===r||e(t,c,{get:()=>o[c],enumerable:!(a=n(o,c))||a.enumerable});return t})(!a&&r&&r.__esModule?c:e(c,"default",{value:r,enumerable:!0}),r)),c=r({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),h=r({"node_modules/kind-of/index.js"(t,e){var n=c(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),l=r({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),d=r({"node_modules/deep-rename-keys/index.js"(t,e){var n=h(),s=l();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),u=r({"node_modules/xml-reader/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),p=r({"node_modules/xml-lexer/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),f=r({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=p(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),m=r({"node_modules/xml-reader/dist/reader.js"(t,e){var n=u(),s=f(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}});function g(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function y(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}var{cos:x,sin:v,PI:b}=Math,{tan:P}=Math;a(d()),a(m());function S(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var M=(t,e)=>({...t,rects:[...t.rects??[],...e.rects??[]],points:[...t.points??[],...e.points??[]],lines:[...t.lines??[],...e.lines??[]],circles:[...t.circles??[],...e.circles??[]],arrows:[...t.arrows??[],...e.arrows??[]],texts:[...t.texts??[],...e.texts??[]]}),N=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function I(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var _=class extends N{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(S(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(S(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(S(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},C=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,e){let n=this.length++;for(;n>0;){const t=n-1>>1,s=this.values[t];if(e>=s)break;this.ids[n]=this.ids[t],this.values[n]=s,n=t}this.ids[n]=t,this.values[n]=e}pop(){if(0===this.length)return;const t=this.ids,e=this.values,n=t[0],s=--this.length;if(s>0){const n=t[s],o=e[s];let i=0;const r=s>>1;for(;i<r;){const n=1+(i<<1),r=n+1,a=n+(+(r<s)&+(e[r]<e[n]));if(e[a]>=o)break;t[i]=t[a],e[i]=e[a],i=a}t[i]=n,e[i]=o}return n}peek(){return this.length>0?this.ids[0]:void 0}peekValue(){return this.length>0?this.values[0]:void 0}shrink(){this.ids.length=this.values.length=this.length}},T=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],E=class t{static from(e,n=0){if(n%8!=0)throw new Error("byteOffset must be 8-byte aligned.");if(!e||void 0===e.byteLength||e.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[s,o]=new Uint8Array(e,n+0,2);if(251!==s)throw new Error("Data does not appear to be in a Flatbush format.");const i=o>>4;if(3!==i)throw new Error(`Got v${i} data when expected v3.`);const r=T[15&o];if(!r)throw new Error("Unrecognized array type.");const[a]=new Uint16Array(e,n+2,1),[c]=new Uint32Array(e,n+4,1);return new t(c,a,r,void 0,e,n)}constructor(t,e=16,n=Float64Array,s=ArrayBuffer,o,i=0){if(void 0===t)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=i;let r=t,a=r;this._levelBounds=[4*r];do{r=Math.ceil(r/this.nodeSize),a+=r,this._levelBounds.push(4*a)}while(1!==r);this.ArrayType=n,this.IndexArrayType=a<16384?Uint16Array:Uint32Array;const c=T.indexOf(n),h=4*a*n.BYTES_PER_ELEMENT;if(c<0)throw new Error(`Unexpected typed array class: ${n}.`);if(o)this.data=o,this._boxes=new n(o,i+8,4*a),this._indices=new this.IndexArrayType(o,i+8+h,a),this._pos=4*a,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1];else{const o=this.data=new s(8+h+a*this.IndexArrayType.BYTES_PER_ELEMENT);this._boxes=new n(o,8,4*a),this._indices=new this.IndexArrayType(o,8+h,a),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(o,0,2).set([251,48+c]),new Uint16Array(o,2,1)[0]=e,new Uint32Array(o,4,1)[0]=t}this._queue=new C}add(t,e,n=t,s=e){const o=this._pos>>2,i=this._boxes;return this._indices[o]=o,i[this._pos++]=t,i[this._pos++]=e,i[this._pos++]=n,i[this._pos++]=s,t<this.minX&&(this.minX=t),e<this.minY&&(this.minY=e),n>this.maxX&&(this.maxX=n),s>this.maxY&&(this.maxY=s),o}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);const t=this._boxes;if(this.numItems<=this.nodeSize)return t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,void(t[this._pos++]=this.maxY);const e=this.maxX-this.minX||1,n=this.maxY-this.minY||1,s=new Uint32Array(this.numItems);for(let o=0,i=0;o<this.numItems;o++){const r=t[i++],a=t[i++],c=t[i++],h=t[i++],l=Math.floor(65535*((r+c)/2-this.minX)/e),d=Math.floor(65535*((a+h)/2-this.minY)/n);s[o]=A(l,d)}R(s,t,this._indices,0,this.numItems-1,this.nodeSize);for(let e=0,n=0;e<this._levelBounds.length-1;e++){const s=this._levelBounds[e];for(;n<s;){const e=n;let o=t[n++],i=t[n++],r=t[n++],a=t[n++];for(let e=1;e<this.nodeSize&&n<s;e++)o=Math.min(o,t[n++]),i=Math.min(i,t[n++]),r=Math.max(r,t[n++]),a=Math.max(a,t[n++]);this._indices[this._pos>>2]=e,t[this._pos++]=o,t[this._pos++]=i,t[this._pos++]=r,t[this._pos++]=a}}}search(t,e,n,s,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=[],a=[];for(;void 0!==i;){const c=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let h=i;h<c;h+=4){const c=this._boxes[h];if(n<c)continue;const l=this._boxes[h+1];if(s<l)continue;const d=this._boxes[h+2];if(t>d)continue;const u=this._boxes[h+3];if(e>u)continue;const p=0|this._indices[h>>2];i>=4*this.numItems?r.push(p):(void 0===o||o(p,c,l,d,u))&&a.push(p)}i=r.pop()}return a}neighbors(t,e,n=1/0,s=1/0,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=this._queue,a=[],c=s*s;t:for(;void 0!==i;){const s=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let n=i;n<s;n+=4){const s=0|this._indices[n>>2],a=this._boxes[n],h=this._boxes[n+1],l=this._boxes[n+2],d=this._boxes[n+3],u=t<a?a-t:t>l?t-l:0,p=e<h?h-e:e>d?e-d:0,f=u*u+p*p;f>c||(i>=4*this.numItems?r.push(s<<1,f):(void 0===o||o(s))&&r.push(1+(s<<1),f))}for(;r.length&&1&r.peek();){if(r.peekValue()>c)break t;if(a.push(r.pop()>>1),a.length===n)break t}i=r.length?r.pop()>>1:void 0}return r.clear(),a}};function w(t,e){let n=0,s=e.length-1;for(;n<s;){const o=n+s>>1;e[o]>t?s=o:n=o+1}return e[n]}function R(t,e,n,s,o,i){if(Math.floor(s/i)>=Math.floor(o/i))return;const r=t[s],a=t[s+o>>1],c=t[o];let h=c;const l=Math.max(r,a);c>l?h=l:l===r?h=Math.max(a,c):l===a&&(h=Math.max(r,c));let d=s-1,u=o+1;for(;;){do{d++}while(t[d]<h);do{u--}while(t[u]>h);if(d>=u)break;O(t,e,n,d,u)}R(t,e,n,s,u,i),R(t,e,n,u+1,o,i)}function O(t,e,n,s,o){const i=t[s];t[s]=t[o],t[o]=i;const r=4*s,a=4*o,c=e[r],h=e[r+1],l=e[r+2],d=e[r+3];e[r]=e[a],e[r+1]=e[a+1],e[r+2]=e[a+2],e[r+3]=e[a+3],e[a]=c,e[a+1]=h,e[a+2]=l,e[a+3]=d;const u=n[s];n[s]=n[o],n[o]=u}function A(t,e){let n=t^e,s=65535^n,o=65535^(t|e),i=t&(65535^e),r=n|s>>1,a=n>>1^n,c=o>>1^s&i>>1^o,h=n&o>>1^i>>1^i;n=r,s=a,o=c,i=h,r=n&n>>2^s&s>>2,a=n&s>>2^s&(n^s)>>2,c^=n&o>>2^s&i>>2,h^=s&o>>2^(n^s)&i>>2,n=r,s=a,o=c,i=h,r=n&n>>4^s&s>>4,a=n&s>>4^s&(n^s)>>4,c^=n&o>>4^s&i>>4,h^=s&o>>4^(n^s)&i>>4,n=r,s=a,o=c,i=h,c^=n&o>>8^s&i>>8,h^=s&o>>8^(n^s)&i>>8,n=c^c>>1,s=h^h>>1;let l=t^e,d=s|65535^(l|n);return l=16711935&(l|l<<8),l=252645135&(l|l<<4),l=858993459&(l|l<<2),l=1431655765&(l|l<<1),d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),(d<<1|l)>>>0}function z(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}function L(t,e,n){return Math.max(e,Math.min(n,t))}function D(t,e,n,s){const o=F(t,e,n),i=F(t,e,s),r=F(n,s,t),a=F(n,s,e);return o!==i&&r!==a||(!(0!==o||!Y(t,n,e))||(!(0!==i||!Y(t,s,e))||(!(0!==r||!Y(n,t,s))||!(0!==a||!Y(n,e,s)))))}function F(t,e,n){const s=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===s?0:s>0?1:2}function Y(t,e,n){return e.x<=Math.max(t.x,n.x)&&e.x>=Math.min(t.x,n.x)&&e.y<=Math.max(t.y,n.y)&&e.y>=Math.min(t.y,n.y)}function X(t,e,n){const s=(n.x-e.x)**2+(n.y-e.y)**2;if(0===s)return k(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return k(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function k(t,e){const n=t.x-e.x,s=t.y-e.y;return Math.sqrt(n*n+s*s)}function $(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=t.x-n.x,h=t.y-n.y,l=o*a-i*r;if(Math.abs(l)<1e-10)return null;const d=(h*r-c*a)/l,u=(o*h-i*c)/l,p=1e-9;if(d>=-1e-9&&d<=1+p&&u>=-1e-9&&u<=1+p){return{x:t.x+d*o,y:t.y+d*i}}return null}function B(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var j=t=>{if("minX"in t)return t;const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,minY:t.center.y-n,maxX:t.center.x+e,maxY:t.center.y+n}},W=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],H=t=>{const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];e.push([s,o])}return e},U=(t,e,n)=>{const s=(t.y-e.y)*(n.x-e.x)-(t.x-e.x)*(n.y-e.y);if(Math.abs(s)>1e-9)return!1;const o=(t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y);if(o<0)return!1;return!(o>(n.x-e.x)**2+(n.y-e.y)**2)},V=(t,e)=>{if(e.length<3)return!1;const n=H(e);for(const[e,s]of n)if(U(t,e,s))return!0;let s=!1;for(let n=0,o=e.length-1;n<e.length;o=n++){const i=e[n].x,r=e[n].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(s=!s)}return s},G=(t,e)=>{const n=W(t),s=[[n[0],n[1]],[n[1],n[2]],[n[2],n[3]],[n[3],n[0]]],o=H(e);for(const[t,e]of o)for(const[n,o]of s)if(D(t,e,n,o))return!0;return!1},Z=(t,e)=>((t,e)=>!(e.length<3)&&(!!e.some(e=>((t,e)=>t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY)(e,t))||(!!W(t).some(t=>V(t,e))||G(t,e))))(j(t),e),q=(t,e)=>((t,e)=>!(e.length<3)&&(!!W(t).every(t=>V(t,e))&&!G(t,e)))(j(t),e);function J(t,e,n,s){if(t.x===e.x&&t.y===e.y)return X(t,n,s);if(n.x===s.x&&n.y===s.y)return X(n,t,e);if(D(t,e,n,s))return 0;const o=[X(t,n,s),X(e,n,s),X(n,t,e),X(s,t,e)];return Math.min(...o)}function K(t,e,n){const s=n.width/2,o=n.height/2;return function(t,e,n){const s={x:n.minX,y:n.minY},o={x:n.maxX,y:n.minY},i={x:n.minX,y:n.maxY},r={x:n.maxX,y:n.maxY};if(D(t,e,s,o)||D(t,e,o,r)||D(t,e,r,i)||D(t,e,i,s))return 0;if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY&&e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;const a=[X(s,t,e),X(o,t,e),X(i,t,e),X(r,t,e)];if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY)return 0;if(e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;if(t.x<n.minX||t.x>n.maxX||t.y<n.minY||t.y>n.maxY){const e=L(t.x,n.minX,n.maxX),s=L(t.y,n.minY,n.maxY);a.push(k(t,{x:e,y:s}))}if(e.x<n.minX||e.x>n.maxX||e.y<n.minY||e.y>n.maxY){const t=L(e.x,n.minX,n.maxX),s=L(e.y,n.minY,n.maxY);a.push(k(e,{x:t,y:s}))}return Math.min(...a)}(t,e,{minX:n.center.x-s,maxX:n.center.x+s,minY:n.center.y-o,maxY:n.center.y+o})}function Q(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(0===i)return{x:e.x,y:e.y};let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;r=Math.max(0,Math.min(1,r));return{x:e.x+r*s,y:e.y+r*o}}function tt(t,e,n=0,s=t.length-1,o=nt){for(;s>n;){if(s-n>600){const i=s-n+1,r=e-n+1,a=Math.log(i),c=.5*Math.exp(2*a/3),h=.5*Math.sqrt(a*c*(i-c)/i)*(r-i/2<0?-1:1);tt(t,e,Math.max(n,Math.floor(e-r*c/i+h)),Math.min(s,Math.floor(e+(i-r)*c/i+h)),o)}const i=t[e];let r=n,a=s;for(et(t,n,e),o(t[s],i)>0&&et(t,n,s);r<a;){for(et(t,r,a),r++,a--;o(t[r],i)<0;)r++;for(;o(t[a],i)>0;)a--}0===o(t[n],i)?et(t,n,a):(a++,et(t,a,s)),a<=e&&(n=a+1),e<=a&&(s=a-1)}}function et(t,e,n){const s=t[e];t[e]=t[n],t[n]=s}function nt(t,e){return t<e?-1:t>e?1:0}var st=class{constructor(t=9){this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}all(){return this._all(this.data,[])}search(t){let e=this.data;const n=[];if(!mt(t,e))return n;const s=this.toBBox,o=[];for(;e;){for(let i=0;i<e.children.length;i++){const r=e.children[i],a=e.leaf?s(r):r;mt(t,a)&&(e.leaf?n.push(r):ft(t,a)?this._all(r,n):o.push(r))}e=o.pop()}return n}collides(t){let e=this.data;if(!mt(t,e))return!1;const n=[];for(;e;){for(let s=0;s<e.children.length;s++){const o=e.children[s],i=e.leaf?this.toBBox(o):o;if(mt(t,i)){if(e.leaf||ft(t,i))return!0;n.push(o)}}e=n.pop()}return!1}load(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(let e=0;e<t.length;e++)this.insert(t[e]);return this}let e=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===e.height)this._splitRoot(this.data,e);else{if(this.data.height<e.height){const t=this.data;this.data=e,e=t}this._insert(e,this.data.height-e.height-1,!0)}else this.data=e;return this}insert(t){return t&&this._insert(t,this.data.height-1),this}clear(){return this.data=gt([]),this}remove(t,e){if(!t)return this;let n=this.data;const s=this.toBBox(t),o=[],i=[];let r,a,c;for(;n||o.length;){if(n||(n=o.pop(),a=o[o.length-1],r=i.pop(),c=!0),n.leaf){const s=ot(t,n.children,e);if(-1!==s)return n.children.splice(s,1),o.push(n),this._condense(o),this}c||n.leaf||!ft(n,s)?a?(r++,n=a.children[r],c=!1):n=null:(o.push(n),i.push(r),r=0,a=n,n=n.children[0])}return this}toBBox(t){return t}compareMinX(t,e){return t.minX-e.minX}compareMinY(t,e){return t.minY-e.minY}toJSON(){return this.data}fromJSON(t){return this.data=t,this}_all(t,e){const n=[];for(;t;)t.leaf?e.push(...t.children):n.push(...t.children),t=n.pop();return e}_build(t,e,n,s){const o=n-e+1;let i,r=this._maxEntries;if(o<=r)return i=gt(t.slice(e,n+1)),it(i,this.toBBox),i;s||(s=Math.ceil(Math.log(o)/Math.log(r)),r=Math.ceil(o/Math.pow(r,s-1))),i=gt([]),i.leaf=!1,i.height=s;const a=Math.ceil(o/r),c=a*Math.ceil(Math.sqrt(r));yt(t,e,n,c,this.compareMinX);for(let o=e;o<=n;o+=c){const e=Math.min(o+c-1,n);yt(t,o,e,a,this.compareMinY);for(let n=o;n<=e;n+=a){const o=Math.min(n+a-1,e);i.children.push(this._build(t,n,o,s-1))}}return it(i,this.toBBox),i}_chooseSubtree(t,e,n,s){for(;s.push(e),!e.leaf&&s.length-1!==n;){let n,s=1/0,o=1/0;for(let i=0;i<e.children.length;i++){const r=e.children[i],a=lt(r),c=ut(t,r)-a;c<o?(o=c,s=a<s?a:s,n=r):c===o&&a<s&&(s=a,n=r)}e=n||e.children[0]}return e}_insert(t,e,n){const s=n?t:this.toBBox(t),o=[],i=this._chooseSubtree(s,this.data,e,o);for(i.children.push(t),at(i,s);e>=0&&o[e].children.length>this._maxEntries;)this._split(o,e),e--;this._adjustParentBBoxes(s,o,e)}_split(t,e){const n=t[e],s=n.children.length,o=this._minEntries;this._chooseSplitAxis(n,o,s);const i=this._chooseSplitIndex(n,o,s),r=gt(n.children.splice(i,n.children.length-i));r.height=n.height,r.leaf=n.leaf,it(n,this.toBBox),it(r,this.toBBox),e?t[e-1].children.push(r):this._splitRoot(n,r)}_splitRoot(t,e){this.data=gt([t,e]),this.data.height=t.height+1,this.data.leaf=!1,it(this.data,this.toBBox)}_chooseSplitIndex(t,e,n){let s,o=1/0,i=1/0;for(let r=e;r<=n-e;r++){const e=rt(t,0,r,this.toBBox),a=rt(t,r,n,this.toBBox),c=pt(e,a),h=lt(e)+lt(a);c<o?(o=c,s=r,i=h<i?h:i):c===o&&h<i&&(i=h,s=r)}return s||n-e}_chooseSplitAxis(t,e,n){const s=t.leaf?this.compareMinX:ct,o=t.leaf?this.compareMinY:ht;this._allDistMargin(t,e,n,s)<this._allDistMargin(t,e,n,o)&&t.children.sort(s)}_allDistMargin(t,e,n,s){t.children.sort(s);const o=this.toBBox,i=rt(t,0,e,o),r=rt(t,n-e,n,o);let a=dt(i)+dt(r);for(let s=e;s<n-e;s++){const e=t.children[s];at(i,t.leaf?o(e):e),a+=dt(i)}for(let s=n-e-1;s>=e;s--){const e=t.children[s];at(r,t.leaf?o(e):e),a+=dt(r)}return a}_adjustParentBBoxes(t,e,n){for(let s=n;s>=0;s--)at(e[s],t)}_condense(t){for(let e,n=t.length-1;n>=0;n--)0===t[n].children.length?n>0?(e=t[n-1].children,e.splice(e.indexOf(t[n]),1)):this.clear():it(t[n],this.toBBox)}};function ot(t,e,n){if(!n)return e.indexOf(t);for(let s=0;s<e.length;s++)if(n(t,e[s]))return s;return-1}function it(t,e){rt(t,0,t.children.length,e,t)}function rt(t,e,n,s,o){o||(o=gt(null)),o.minX=1/0,o.minY=1/0,o.maxX=-1/0,o.maxY=-1/0;for(let i=e;i<n;i++){const e=t.children[i];at(o,t.leaf?s(e):e)}return o}function at(t,e){return t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),t}function ct(t,e){return t.minX-e.minX}function ht(t,e){return t.minY-e.minY}function lt(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function dt(t){return t.maxX-t.minX+(t.maxY-t.minY)}function ut(t,e){return(Math.max(e.maxX,t.maxX)-Math.min(e.minX,t.minX))*(Math.max(e.maxY,t.maxY)-Math.min(e.minY,t.minY))}function pt(t,e){const n=Math.max(t.minX,e.minX),s=Math.max(t.minY,e.minY),o=Math.min(t.maxX,e.maxX),i=Math.min(t.maxY,e.maxY);return Math.max(0,o-n)*Math.max(0,i-s)}function ft(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function mt(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function gt(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function yt(t,e,n,s,o){const i=[e,n];for(;i.length;){if((n=i.pop())-(e=i.pop())<=s)continue;const r=e+Math.ceil((n-e)/s/2)*s;tt(t,r,e,n,o),i.push(e,r,r,n)}}var xt=1e-4;var vt=[{facingDirection:"x-",dx:-1,dy:0,startX:-.5,startY:.5,endX:-.5,endY:-.5},{facingDirection:"x+",dx:1,dy:0,startX:.5,startY:.5,endX:.5,endY:-.5},{facingDirection:"y-",dx:0,dy:-1,startX:-.5,startY:-.5,endX:.5,endY:-.5},{facingDirection:"y+",dx:0,dy:1,startX:.5,startY:.5,endX:-.5,endY:.5}],bt={"x-":vt.find(t=>"x-"===t.facingDirection),"x+":vt.find(t=>"x+"===t.facingDirection),"y-":vt.find(t=>"y-"===t.facingDirection),"y+":vt.find(t=>"y+"===t.facingDirection)},Pt={"x-":{x:-1,y:0},"x+":{x:1,y:0},"y-":{x:0,y:-1},"y+":{x:0,y:1}},St=(t,e)=>{const{dir:n,amt:s}=e,o=Pt[n];return t.map(t=>({x:t.x+o.x*s,y:t.y+o.y*s}))},Mt=1e-4,Nt=class extends N{constructor(t){super(),this.input=t;for(const t of this.input.meshNodes)for(const e of vt){let n={x:t.center.x+t.width*e.startX,y:t.center.y+t.height*e.startY},s={x:t.center.x+t.width*e.endX,y:t.center.y+t.height*e.endY};n.x>s.x&&([n,s]=[s,n]),Math.abs(n.x-s.x)<Mt&&n.y>s.y&&([n,s]=[s,n]);for(const o of t.availableZ)this.unprocessedEdges.push({parent:t,start:n,end:s,facingDirection:e.facingDirection,z:o})}this.allEdges=[...this.unprocessedEdges],this.edgeSpatialIndex=new E(this.allEdges.length);for(const t of this.allEdges)this.edgeSpatialIndex.add(t.start.x,t.start.y,t.end.x,t.end.y);this.edgeSpatialIndex.finish()}allEdges;unprocessedEdges=[];segmentsWithAdjacentEmptySpace=[];edgeSpatialIndex;lastCandidateEdge=null;lastOverlappingEdges=null;lastUncoveredSegments=null;_step(){if(0===this.unprocessedEdges.length)return this.solved=!0,this.lastCandidateEdge=null,this.lastOverlappingEdges=null,void(this.lastUncoveredSegments=null);const t=this.unprocessedEdges.shift();this.lastCandidateEdge=t;const e=this.edgeSpatialIndex.search(t.start.x-Mt,t.start.y-Mt,t.end.x+Mt,t.end.y+Mt).map(t=>this.allEdges[t]).filter(e=>e.z===t.z);this.lastOverlappingEdges=e;const n=function(t,e){const n=Math.abs(t.start.y-t.end.y)<xt,s=Math.abs(t.start.x-t.end.x)<xt;if(!n&&!s)return[];const o=n?"x":"y",i=n?"y":"x",r=t.start[i],a=t.start[o],c=t.end[o],h=Math.min(a,c),l=Math.max(a,c),d=t=>Math.max(h,Math.min(l,t)),u=[];for(const n of e){if(n===t)continue;const e=Math.abs(n.start.y-n.end.y)<xt,s=Math.abs(n.start.x-n.end.x)<xt;if("x"===o&&!e)continue;if("y"===o&&!s)continue;if(Math.abs(n.start[i]-r)>xt)continue;const a=Math.min(n.start[o],n.end[o]),c=Math.max(n.start[o],n.end[o]),h=d(a),l=d(c);l-h>xt&&u.push({s:h,e:l})}if(0===u.length)return[{...t,start:{...t.start},end:{...t.end}}];u.sort((t,e)=>t.s-e.s);const p=[];for(const t of u){const e=p[p.length-1];!e||t.s>e.e+xt?p.push({...t}):e.e=Math.max(e.e,t.e)}const f=[];let m=h;for(const t of p)if(t.s>m+xt&&f.push({s:m,e:t.s}),m=Math.max(m,t.e),m>=l-xt)break;return l>m+xt&&f.push({s:m,e:l}),0===f.length?[]:f.filter(t=>t.e-t.s>xt).map(e=>{const n="x"===o?{x:e.s,y:r}:{x:r,y:e.s},s="x"===o?{x:e.e,y:r}:{x:r,y:e.e};return{parent:t.parent,facingDirection:t.facingDirection,start:n,end:s,z:t.z}})}(t,e);this.lastUncoveredSegments=n,this.segmentsWithAdjacentEmptySpace.push(...n)}getOutput(){return{segmentsWithAdjacentEmptySpace:this.segmentsWithAdjacentEmptySpace}}visualize(){const t={title:"FindSegmentsWithAdjacentEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)"});for(const e of this.unprocessedEdges)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:-.1}),strokeColor:"rgba(0, 0, 255, 0.5)",strokeDash:"5 5"});for(const e of this.segmentsWithAdjacentEmptySpace)t.lines.push({points:[e.start,e.end],strokeColor:"rgba(0,255,0, 0.5)"});if(this.lastCandidateEdge&&t.lines.push({points:[this.lastCandidateEdge.start,this.lastCandidateEdge.end],strokeColor:"blue"}),this.lastOverlappingEdges)for(const e of this.lastOverlappingEdges)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:.05}),strokeColor:"red",strokeDash:"2 2"});if(this.lastUncoveredSegments)for(const e of this.lastUncoveredSegments)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:-.05}),strokeColor:"green",strokeDash:"2 2"});return t}},It=t=>({minX:Math.min(...t.map(t=>t.x)),minY:Math.min(...t.map(t=>t.y)),maxX:Math.max(...t.map(t=>t.x)),maxY:Math.max(...t.map(t=>t.y))}),_t=1e-4,Ct=class extends N{constructor(t){super(),this.input=t,this.unprocessedSegments=[...this.input.segmentsWithAdjacentEmptySpace],this.rectSpatialIndex=new st,this.rectSpatialIndex.load(this.input.boardVoid?.boardVoidRects.map((t,e)=>({capacityMeshNodeId:`void-rect-${e}`,center:{x:t.x+t.width/2,y:t.y+t.height/2},width:t.width,height:t.height,availableZ:Array.from({length:this.input.boardVoid?.layerCount||0},(t,e)=>e),layer:"void",minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))||[]),this.rectSpatialIndex.load(this.input.inputMeshNodes.map(t=>({...t,minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2})))}unprocessedSegments=[];expandedSegments=[];lastSegment=null;lastSearchBounds=null;lastCollidingNodes=null;lastSearchCorner1=null;lastSearchCorner2=null;lastExpandedSegment=null;rectSpatialIndex;_step(){if(0===this.unprocessedSegments.length)return void(this.solved=!0);const t=this.unprocessedSegments.shift();this.lastSegment=t;const{dx:e,dy:n}=bt[t.facingDirection],s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=Math.sqrt(s**2+o**2),r=s/i,a=o/i;let c=null,h=1;const l={x:t.start.x+e*_t+r*_t*10,y:t.start.y+n*_t+a*_t*10},d={x:t.end.x+e*_t-r*_t*10,y:t.end.y+n*_t-a*_t*10};for(this.lastSearchCorner1=l,this.lastSearchCorner2=d;(!c||0===c.length)&&h<1e3;){const s=It([l,d,{x:l.x+e*h,y:l.y+n*h},{x:d.x+e*h,y:d.y+n*h}]);this.lastSearchBounds=s,c=this.rectSpatialIndex.search(s).filter(e=>e.availableZ.includes(t.z)).filter(e=>e.capacityMeshNodeId!==t.parent.capacityMeshNodeId),h*=4}if(!c||0===c.length)return;this.lastCollidingNodes=c;let u=1/0;for(const e of c){const n=K(t.start,t.end,e);n<u&&(u=n)}const p=u,f=It([t.start,t.end,{x:t.start.x+e*p,y:t.start.y+n*p},{x:t.end.x+e*p,y:t.end.y+n*p}]),m={x:(f.minX+f.maxX)/2,y:(f.minY+f.maxY)/2},g=f.maxX-f.minX,y=f.maxY-f.minY,x={segment:t,newNode:{capacityMeshNodeId:`new-${t.parent.capacityMeshNodeId}-${this.expandedSegments.length}`,center:m,width:g,height:y,availableZ:[t.z],layer:t.parent.layer}};this.lastExpandedSegment=x,g<_t||y<_t||(this.expandedSegments.push(x),this.rectSpatialIndex.insert({...x.newNode,...f}))}getOutput(){return{expandedSegments:this.expandedSegments}}visualize(){const t={title:"ExpandEdgesToEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.inputMeshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});for(const{newNode:e}of this.expandedSegments)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"green",label:`expandedSegment (z=${e.availableZ.join(",")})`,layer:`z${e.availableZ.join(",")}`});if(this.lastSegment&&t.lines.push({points:[this.lastSegment.start,this.lastSegment.end],strokeColor:"rgba(0, 0, 255, 0.5)"}),this.lastSearchBounds&&t.rects.push({center:{x:(this.lastSearchBounds.minX+this.lastSearchBounds.maxX)/2,y:(this.lastSearchBounds.minY+this.lastSearchBounds.maxY)/2},width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:"rgba(0, 0, 255, 0.25)"}),this.lastSearchCorner1&&this.lastSearchCorner2&&(t.points.push({x:this.lastSearchCorner1.x,y:this.lastSearchCorner1.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner1",`z=${this.lastSegment?.z}`].join("\n")}),t.points.push({x:this.lastSearchCorner2.x,y:this.lastSearchCorner2.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner2",`z=${this.lastSegment?.z}`].join("\n")})),this.lastExpandedSegment&&t.rects.push({center:this.lastExpandedSegment.newNode.center,width:this.lastExpandedSegment.newNode.width,height:this.lastExpandedSegment.newNode.height,fill:"purple",label:`expandedSegment (z=${this.lastExpandedSegment.segment.z})`}),this.lastCollidingNodes)for(const e of this.lastCollidingNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255, 0, 0, 0.5)"});return t}},Tt=class extends _{findSegmentsWithAdjacentEmptySpaceSolver;expandEdgesToEmptySpaceSolver;pipelineDef=[I("findSegmentsWithAdjacentEmptySpaceSolver",Nt,t=>[{meshNodes:t.inputProblem.meshNodes}],{onSolved:()=>{}}),I("expandEdgesToEmptySpaceSolver",Ct,t=>[{inputMeshNodes:t.inputProblem.meshNodes,segmentsWithAdjacentEmptySpace:t.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace,boardVoid:t.inputProblem.boardVoid}],{onSolved:()=>{}})];getOutput(){const t=(this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[]).map(t=>t.newNode);return{outputNodes:[...this.inputProblem.meshNodes,...t]}}initialVisualize(){const t={title:"GapFillSolverPipeline - Initial",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.inputProblem.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t={title:"GapFillSolverPipeline - Final",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]},{outputNodes:e}=this.getOutput(),n=this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[],s=new Set(n.map(t=>t.newNode.capacityMeshNodeId));for(const n of e){const e=s.has(n.capacityMeshNodeId);t.rects.push({center:n.center,width:n.width,height:n.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")})}return t}},Et=1e-9,wt=(t,e,n)=>Math.max(e,Math.min(n,t)),Rt=(t,e)=>t>e+Et,Ot=(t,e)=>t>e-Et,At=(t,e)=>t<e-Et,zt=(t,e)=>t<e+Et;function Lt(t,e){return!(t.x+t.width<=e.x+Et||e.x+e.width<=t.x+Et||t.y+t.height<=e.y+Et||e.y+e.height<=t.y+Et)}function Dt(t,e){const n=[[e.x,e.y,e.x+e.width,e.y],[e.x+e.width,e.y,e.x+e.width,e.y+e.height],[e.x+e.width,e.y+e.height,e.x,e.y+e.height],[e.x,e.y+e.height,e.x,e.y]];let s=1/0;for(const[e,o,i,r]of n){const n=t.x-e,a=t.y-o,c=i-e,h=r-o,l=c*c+h*h;let d=0!==l?(n*c+a*h)/l:0;d=wt(d,0,1);const u=e+d*c,p=o+d*h;s=Math.min(s,Math.hypot(t.x-u,t.y-p))}return s}function Ft(t,e){const n=Math.max(t[0],e[0]),s=Math.min(t[1],e[1]);return s>n+Et?[n,s]:null}function Yt(t,e){if(!Lt(t,e))return[t];const n=Ft([t.x,t.x+t.width],[e.x,e.x+e.width]),s=Ft([t.y,t.y+t.height],[e.y,e.y+e.height]);if(!n||!s)return[t];const[o,i]=n,[r,a]=s,c=[];o>t.x+Et&&c.push({x:t.x,y:t.y,width:o-t.x,height:t.height}),t.x+t.width>i+Et&&c.push({x:i,y:t.y,width:t.x+t.width-i,height:t.height});const h=Math.max(0,i-o);return h>Et&&r>t.y+Et&&c.push({x:o,y:t.y,width:h,height:r-t.y}),h>Et&&t.y+t.height>a+Et&&c.push({x:o,y:a,width:h,height:t.y+t.height-a}),c.filter(t=>t.width>Et&&t.height>Et)}function Xt(t,e){let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s].x,r=e[s].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(n=!n)}return n}function kt(t,e){if(!e||e.length<3)return[];const n=e.length>100?function(t,e){const n=t=>Math.round(t/e)*e,s=new Set,o=[];for(const e of t){const t=n(e.x),i=n(e.y),r=`${t},${i}`;s.has(r)||(s.add(r),o.push({x:t,y:i}))}return o}(e,Math.max(t.width,t.height)/100):e,s=new Set([t.x,t.x+t.width]),o=new Set([t.y,t.y+t.height]);for(const t of n)s.add(t.x),o.add(t.y);const i=Array.from(s).sort((t,e)=>t-e),r=Array.from(o).sort((t,e)=>t-e),a=[];for(let n=0;n<i.length-1;n++)for(let s=0;s<r.length-1;s++){const o=i[n],c=i[n+1],h=r[s],l=r[s+1],d=(o+c)/2,u=(h+l)/2;d>=t.x&&d<=t.x+t.width&&u>=t.y&&u<=t.y+t.height&&(Xt({x:d,y:u},e)||a.push({x:o,y:h,width:c-o,height:l-h}))}const c=[];a.sort((t,e)=>Math.abs(t.y-e.y)>Et?t.y-e.y:t.x-e.x);let h=null;for(const t of a){if(!h){h=t;continue}const e=Math.abs(h.y-t.y)<Et,n=Math.abs(h.height-t.height)<Et,s=Math.abs(h.x+h.width-t.x)<Et;e&&n&&s?h.width+=t.width:(c.push(h),h=t)}h&&c.push(h),c.sort((t,e)=>Math.abs(t.x-e.x)>Et?t.x-e.x:t.y-e.y);const l=[];h=null;for(const t of c){if(!h){h=t;continue}const e=Math.abs(h.x-t.x)<Et,n=Math.abs(h.width-t.width)<Et,s=Math.abs(h.y+h.height-t.y)<Et;e&&n&&s?h.height+=t.height:(l.push(h),h=t)}return h&&l.push(h),l}function $t(t){const e=t.toLowerCase();if("top"===e)return-1e6;if("bottom"===e)return 1e6;const n=/^inner(\d+)$/i.exec(e);return n?parseInt(n[1],10)||0:100+e.charCodeAt(0)}function Bt(t){const e=function(t){return Array.from(new Set(t)).sort((t,e)=>{const n=$t(t),s=$t(e);return n!==s?n-s:t.localeCompare(e)})}((t.obstacles??[]).flatMap(t=>t.layers??[])),n=Math.max(1,t.layerCount||e.length||1),s=Array.from({length:n},(t,e)=>0===e?"top":e===n-1?"bottom":`inner${e}`),o=[],i=new Set,r=t=>{const e=t.toLowerCase();i.has(e)||(i.add(e),o.push(t))};s.forEach(r),e.forEach(r);const a=o.slice(0,n),c=new Map;return a.forEach((t,e)=>c.set(t.toLowerCase(),e)),o.slice(a.length).forEach(t=>{const e=t.toLowerCase();c.set(e,(t=>{if(a.length<=1)return 0;if("top"===t)return 0;if("bottom"===t)return a.length-1;const e=/^inner(\d+)$/i.exec(t);if(e){if(a.length<=2)return a.length-1;const t=parseInt(e[1],10),n=a.length-2;return Math.min(n,Math.max(1,Number.isFinite(t)?t:1))}return 0})(e))}),{layerNames:a,zIndexByName:c}}function jt(t,e){if(t.zLayers?.length)return Array.from(new Set(t.zLayers)).sort((t,e)=>t-e);const n=(t.layers??[]).map(t=>e.get(t.toLowerCase())).filter(t=>"number"==typeof t);return Array.from(new Set(n)).sort((t,e)=>t-e)}function Wt(t){const e=t.width,n=t.height;return"number"!=typeof e||"number"!=typeof n?null:{x:t.center.x-e/2,y:t.center.y-n/2,width:e,height:n}}var Ht=1e-9,Ut=t=>Math.abs(t.rect.x+t.rect.width/2-t.startX)<Ht&&Math.abs(t.rect.y+t.rect.height/2-t.startY)<Ht&&Math.abs(t.rect.width-t.initialW)<Ht&&Math.abs(t.rect.height-t.initialH)<Ht,Vt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:e.x+e.width-t.x,height:t.height}),Gt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:t.width,height:e.y+e.height-t.y}),Zt=({rect:t,bounds:e})=>({x:e.x,y:t.y,width:t.x-e.x,height:t.height}),qt=({rect:t,bounds:e})=>({x:t.x,y:e.y,width:t.width,height:t.y-e.y});function Jt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x+n.width-e.x;for(const t of s){if(e.y+e.height>t.y+Et&&t.y+t.height>e.y+Et)if(Ot(t.x,e.x+e.width))i=Math.min(i,t.x-e.x);else if(t.x+t.width>e.x+e.width-Et&&t.x<e.x+e.width+Et)return 0}let r=Math.max(0,i-e.width);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function Kt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y+n.height-e.y;for(const t of s){if(e.x+e.width>t.x+Et&&t.x+t.width>e.x+Et)if(Ot(t.y,e.y+e.height))i=Math.min(i,t.y-e.y);else if(t.y+t.height>e.y+e.height-Et&&t.y<e.y+e.height+Et)return 0}let r=Math.max(0,i-e.height);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}function Qt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x;for(const t of s){if(e.y+e.height>t.y+Et&&t.y+t.height>e.y+Et)if(zt(t.x+t.width,e.x))i=Math.max(i,t.x+t.width);else if(t.x<e.x+Et&&t.x+t.width>e.x-Et)return 0}let r=Math.max(0,e.x-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function te(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y;for(const t of s){if(e.x+e.width>t.x+Et&&t.x+t.width>e.x+Et)if(zt(t.y+t.height,e.y))i=Math.max(i,t.y+t.height);else if(t.y<e.y+Et&&t.y+t.height>e.y-Et)return 0}let r=Math.max(0,e.y-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}var ee=t=>({x:t.minX,y:t.minY,width:t.maxX-t.minX,height:t.maxY-t.minY}),ne=t=>{const{rect:e,seen:n,blockers:s}=t,o=`${e.x}|${e.y}|${e.width}|${e.height}`;n.has(o)||(n.add(o),s.push(e))};function se(t){const{startX:e,startY:n,gridSize:s,bounds:o,obsticalIndexByLayer:i,placedIndexByLayer:r,initialCellRatio:a,maxAspectRatio:c,minReq:h}=t,l=Math.max(1e-9,s*a),d=Math.max(l,h.width),u=Math.max(l,h.height),p=[],f=new Set,m=r.length,g=s=>{const a=(t=>{const{bounds:e,rect:n}=t,s=Math.max(e.x,n.x),o=Math.max(e.y,n.y),i=Math.min(e.x+e.width,n.x+n.width),r=Math.min(e.y+e.height,n.y+n.height);return i<=s+Et||r<=o+Et?null:{minX:s,minY:o,maxX:i,maxY:r}})({bounds:o,rect:s});if(a)for(const s of t.zLayers){const t=i[s];if(t)for(const e of t.search(a))ne({rect:ee(e),seen:f,blockers:p});const o=r[s];if(o)for(const t of o.search(a)){if(!(t.zLayers.length>=m))continue;const s=ee(t);Ut({rect:s,startX:e,startY:n,initialW:d,initialH:u})||ne({rect:s,seen:f,blockers:p})}}},y=[{ox:0,oy:0},{ox:-d,oy:0},{ox:0,oy:-u},{ox:-d,oy:-u},{ox:-d/2,oy:-u/2}];let x=null,v=0;t:for(const t of y){let s={x:e+t.ox,y:n+t.oy,width:d,height:u};if(g(s),At(s.x,o.x)||At(s.y,o.y)||Rt(s.x+s.width,o.x+o.width)||Rt(s.y+s.height,o.y+o.height))continue;for(const t of p)if(Lt(s,t))continue t;const i=1e-6,r=1e3;let a=!0,l=0;for(;a&&l<r;){l++,a=!1;const t={bounds:o,blockers:p,maxAspect:c};g(Vt({rect:s,bounds:o}));const e=Jt({...t,r:s});e>i&&(s={...s,width:s.width+e},g(s),a=!0),g(Gt({rect:s,bounds:o}));const n=Kt({...t,r:s});n>i&&(s={...s,height:s.height+n},g(s),a=!0),g(Zt({rect:s,bounds:o}));const r=Qt({...t,r:s});r>i&&(s={x:s.x-r,y:s.y,width:s.width+r,height:s.height},g(s),a=!0),g(qt({rect:s,bounds:o}));const h=te({...t,r:s});h>i&&(s={x:s.x,y:s.y-h,width:s.width,height:s.height+h},g(s),a=!0)}if(s.width+Et>=h.width&&s.height+Et>=h.height){const t=s.width*s.height;t>v&&(x=s,v=t)}}return x}function oe(t){const e=Math.max(t.width,t.height);return[e/8,e/16,e/32]}function ie(t){const e={minX:t.point.x,minY:t.point.y,maxX:t.point.x,maxY:t.point.y};for(let n=0;n<t.layerCount;n++){const s=t.obstacleIndexByLayer[n],o=!!s&&s.search(e).length>0,i=t.placedIndexByLayer[n],r=!!i&&i.search(e).length>0;if(!o&&!r)return!1}return!0}function re(t){const{x:e,y:n,z:s,layerCount:o,minSpan:i,maxSpan:r,obstacleIndexByLayer:a,additionalBlockersByLayer:c}=t,h=t=>{const s={minX:e,minY:n,maxX:e,maxY:n},o=a[t];if(o&&o.search(s).length>0)return!1;return!(c?.[t]??[]).some(t=>{return(o={x:e,y:n}).x>=(s=t).x-Et&&o.x<=s.x+s.width+Et&&o.y>=s.y-Et&&o.y<=s.y+s.height+Et;var s,o})};let l=s,d=s;for(;l-1>=0&&h(l-1);)l--;for(;d+1<o&&h(d+1);)d++;if("number"==typeof r){const t=wt(r,1,o);for(;d-l+1>t;)s-l>d-s?l++:d--}const u=[];for(let t=l;t<=d;t++)u.push(t);return u.length>=i?u:[]}function ae(t){const{lineStart:e,lineEnd:n,coveringIntervals:s,minSegmentLength:o}=t;if(0===s.length){return[{start:e,end:n,center:(e+n)/2}]}const i=[...s].sort((t,e)=>t.start-e.start),r=[];let a={...i[0]};for(let t=1;t<i.length;t++){const e=i[t];e.start<=a.end+Et?a.end=Math.max(a.end,e.end):(r.push(a),a={...e})}r.push(a);const c=[];if(r[0].start>e+Et){const t=e,n=r[0].start;n-t>=o&&c.push({start:t,end:n,center:(t+n)/2})}for(let t=0;t<r.length-1;t++){const e=r[t].end,n=r[t+1].start;n-e>=o&&c.push({start:e,end:n,center:(e+n)/2})}if(r[r.length-1].end<n-Et){const t=r[r.length-1].end,e=n;e-t>=o&&c.push({start:t,end:e,center:(t+e)/2})}return c}function ce(t){const{bounds:e,minSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=[],c=Math.max(.15*n,3*Et),h=new Set;function l(t){const{x:n,y:c,z:l}=t;if(n<e.x+Et||c<e.y+Et||n>e.x+e.width-Et||c>e.y+e.height-Et)return;if(function(t){return ie({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:t})}({x:n,y:c}))return;const d=[...o[l]?.all()??[],...r[l]??[]],u=Math.min(Dt({x:n,y:c},e),...d.length?d.map(t=>Dt({x:n,y:c},t)):[1/0]),p=(t=>`${t.z}|${t.x.toFixed(6)}|${t.y.toFixed(6)}`)({x:n,y:c,z:l});if(h.has(p))return;h.add(p);const f=re({x:n,y:c,z:l,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});a.push({x:n,y:c,z:l,distance:u,zSpanLen:f.length,isEdgeSeed:!0})}for(let t=0;t<s;t++){const s=[...o[t]?.all()??[],...r[t]??[]],i=[{x:e.x+c,y:e.y+c},{x:e.x+e.width-c,y:e.y+c},{x:e.x+c,y:e.y+e.height-c},{x:e.x+e.width-c,y:e.y+e.height-c}];for(const e of i)l({x:e.x,y:e.y,z:t});const a=e.y+c,h=s.filter(t=>t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),d=ae({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:h,minSegmentLength:.5*n});for(const e of d){const s=e.end-e.start;s>=n&&(l({x:e.center,y:a,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:a,z:t}),l({x:e.end-.4*n,y:a,z:t})))}const u=e.y+e.height-c,p=s.filter(t=>t.y<=u&&t.y+t.height>=u).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),f=ae({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:p,minSegmentLength:.5*n});for(const e of f){const s=e.end-e.start;s>=n&&(l({x:e.center,y:u,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:u,z:t}),l({x:e.end-.4*n,y:u,z:t})))}const m=e.x+c,g=s.filter(t=>t.x<=m&&t.x+t.width>=m).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),y=ae({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:g,minSegmentLength:.5*n});for(const e of y){const s=e.end-e.start;s>=n&&(l({x:m,y:e.center,z:t}),s>1.5*n&&(l({x:m,y:e.start+.4*n,z:t}),l({x:m,y:e.end-.4*n,z:t})))}const x=e.x+e.width-c,v=s.filter(t=>t.x<=x&&t.x+t.width>=x).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),b=ae({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:v,minSegmentLength:.5*n});for(const e of b){const s=e.end-e.start;s>=n&&(l({x:x,y:e.center,z:t}),s>1.5*n&&(l({x:x,y:e.start+.4*n,z:t}),l({x:x,y:e.end-.4*n,z:t})))}for(const o of s){const i=o.x-c;if(i>e.x+Et&&i<e.x+e.width-Et){const e=s.filter(t=>t!==o&&t.x<=i&&t.x+t.width>=i).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),r=ae({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)l({x:i,y:e.center,z:t})}const r=o.x+o.width+c;if(r>e.x+Et&&r<e.x+e.width-Et){const e=s.filter(t=>t!==o&&t.x<=r&&t.x+t.width>=r).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),i=ae({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:r,y:e.center,z:t})}const a=o.y-c;if(a>e.y+Et&&a<e.y+e.height-Et){const e=s.filter(t=>t!==o&&t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ae({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:a,z:t})}const h=o.y+o.height+c;if(h>e.y+Et&&h<e.y+e.height-Et){const e=s.filter(t=>t!==o&&t.y<=h&&t.y+t.height>=h).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ae({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:h,z:t})}}}return a.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),a}var he=(t,e)=>({...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:e.zLayers});function le(t,e){const n=t.placed[e],{rect:s,zLayers:o}=n,i=t.layerCount,r=[],a=[];for(let n=0;n<t.placed.length;n++){if(n===e)continue;const c=t.placed[n];if(c.zLayers.length>=i)continue;const h=c.zLayers.filter(t=>o.includes(t));if(0===h.length)continue;if(!Lt(c.rect,s))continue;const l=Yt(c.rect,s);r.push(n);const d=c.zLayers.filter(t=>!o.includes(t));d.length>0&&a.push({rect:c.rect,zLayers:d});const u=Math.min(t.options.minSingle.width,t.options.minMulti.width),p=Math.min(t.options.minSingle.height,t.options.minMulti.height);for(const t of l)t.width+Et>=u&&t.height+Et>=p&&a.push({rect:t,zLayers:h.slice()})}const c=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY;r.sort((t,e)=>e-t).forEach(e=>{const n=t.placed.splice(e,1)[0];if(t.placedIndexByLayer)for(const e of n.zLayers){const s=t.placedIndexByLayer[e];s&&s.remove(he(n.rect,{zLayers:n.zLayers}),c)}});for(const e of a){t.placed.push(e);for(const n of e.zLayers)if(t.placedIndexByLayer){const s=t.placedIndexByLayer[n];s&&s.insert(he(e.rect,{zLayers:e.zLayers.slice()}))}}}var de=t=>{const e=[{fill:"#dbeafe",stroke:"#3b82f6"},{fill:"#fef3c7",stroke:"#f59e0b"},{fill:"#d1fae5",stroke:"#10b981"},{fill:"#e9d5ff",stroke:"#a855f7"},{fill:"#fed7aa",stroke:"#f97316"},{fill:"#fecaca",stroke:"#ef4444"}];return e[Math.min(...t)%e.length]},ue=class extends N{constructor(t){super(),this.input=t}srj;layerNames;layerCount;bounds;options;boardVoidRects;gridIndex;candidates;placed;placedIndexByLayer;expansionIndex;edgeAnalysisDone;totalSeedsThisGrid;consumedSeedsThisGrid;_setup(){const t=this.input.simpleRouteJson,e=this.input.gridOptions??{},{layerNames:n,zIndexByName:s}=Bt(t),o=Math.max(1,n.length,t.layerCount||1),i={x:t.bounds.minX,y:t.bounds.minY,width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},r=Math.max(.01,t.minTraceWidth||.15),a={...{gridSizes:[],initialCellRatio:.2,maxAspectRatio:3,minSingle:{width:2*r,height:2*r},minMulti:{width:4*r,height:4*r,minLayers:Math.min(2,Math.max(1,t.layerCount||1))},preferMultiLayer:!0,maxMultiLayerSpan:void 0},...e,gridSizes:e.gridSizes??oe(i)};this.srj=t,this.layerNames=n,this.layerCount=o,this.bounds=i,this.options=a,this.boardVoidRects=this.input.boardVoidRects,this.gridIndex=0,this.candidates=[],this.placed=[],this.placedIndexByLayer=Array.from({length:o},()=>new st),this.expansionIndex=0,this.edgeAnalysisDone=!1,this.totalSeedsThisGrid=0,this.consumedSeedsThisGrid=0,this.stats={gridIndex:this.gridIndex}}_step(){this._stepGrid(),this.stats.gridIndex=this.gridIndex,this.stats.placed=this.placed.length}_stepGrid(){const{gridSizes:t,initialCellRatio:e,maxAspectRatio:n,minSingle:s,minMulti:o,preferMultiLayer:i,maxMultiLayerSpan:r}=this.options,a=t[this.gridIndex],c=function(t){const e=Array.from({length:t.layerCount},()=>[]);for(const n of t.placed)if(n.zLayers.length>=t.layerCount)for(const t of n.zLayers)e[t].push(n.rect);return e}({layerCount:this.layerCount,placed:this.placed});if(0===this.candidates.length&&0===this.consumedSeedsThisGrid&&(this.candidates=function(t){const{bounds:e,gridSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=new Map;for(let t=e.x;t<e.x+e.width;t+=n)for(let c=e.y;c<e.y+e.height;c+=n){if(Math.abs(t-e.x)<Et||Math.abs(c-e.y)<Et||t>e.x+e.width-n-Et||c>e.y+e.height-n-Et)continue;if(ie({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:{x:t,y:c}}))continue;let h=[],l=0;for(let e=0;e<s;e++){const n=re({x:t,y:c,z:e,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});n.length>h.length&&(h=n,l=e)}const d=h.length?h[Math.floor(h.length/2)]:l,u=[...o[d]?.all()??[],...r[d]??[]],p=Math.min(Dt({x:t,y:c},e),...u.length?u.map(e=>Dt({x:t,y:c},e)):[1/0]),f=`${t.toFixed(6)}|${c.toFixed(6)}`,m={x:t,y:c,z:d,distance:p,zSpanLen:h.length},g=a.get(f);(!g||m.zSpanLen>(g.zSpanLen??0)||m.zSpanLen===g.zSpanLen&&m.distance>g.distance)&&a.set(f,m)}const c=Array.from(a.values());return c.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),c}({bounds:this.bounds,gridSize:a,layerCount:this.layerCount,hardPlacedByLayer:c,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer}),this.totalSeedsThisGrid=this.candidates.length,this.consumedSeedsThisGrid=0),0===this.candidates.length){if(this.gridIndex+1<t.length)return this.gridIndex+=1,this.totalSeedsThisGrid=0,void(this.consumedSeedsThisGrid=0);if(!this.edgeAnalysisDone){const t=Math.min(s.width,s.height);return this.candidates=ce({bounds:this.bounds,minSize:t,layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,hardPlacedByLayer:c}),this.edgeAnalysisDone=!0,this.totalSeedsThisGrid=this.candidates.length,void(this.consumedSeedsThisGrid=0)}return this.solved=!0,void(this.expansionIndex=0)}const h=this.candidates.shift();this.consumedSeedsThisGrid+=1;const l=re({x:h.x,y:h.y,z:h.z,layerCount:this.layerCount,minSpan:o.minLayers,maxSpan:r,obstacleIndexByLayer:this.input.obstacleIndexByLayer,additionalBlockersByLayer:c}),d=[];l.length>=o.minLayers&&d.push({kind:"multi",layers:l,minReq:{width:o.width,height:o.height}}),d.push({kind:"single",layers:[h.z],minReq:{width:s.width,height:s.height}});const u=i?d:d.reverse();for(const t of u){const s=se({startX:h.x,startY:h.y,gridSize:a,bounds:this.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:e,maxAspectRatio:n,minReq:t.minReq,zLayers:t.layers});if(!s)continue;const o={rect:s,zLayers:[...t.layers]},i=this.placed.push(o)-1;for(const e of t.layers){const t=this.placedIndexByLayer[e];t&&t.insert(he(s,{zLayers:o.zLayers}))}return le({layerCount:this.layerCount,placed:this.placed,options:this.options,placedIndexByLayer:this.placedIndexByLayer},i),void(this.candidates=this.candidates.filter(t=>!ie({layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,point:{x:t.x,y:t.y}})))}}computeProgress(){if(this.solved)return 1;const t=this.options.gridSizes.length,e=this.gridIndex/(t+1),n=Math.max(1,this.totalSeedsThisGrid),s=n?this.consumedSeedsThisGrid/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){return{srj:this.srj,layerNames:this.layerNames,layerCount:this.layerCount,bounds:this.bounds,options:this.options,boardVoidRects:this.boardVoidRects,gridIndex:this.gridIndex,candidates:this.candidates,placed:this.placed,expansionIndex:this.expansionIndex,edgeAnalysisDone:this.edgeAnalysisDone,totalSeedsThisGrid:this.totalSeedsThisGrid,consumedSeedsThisGrid:this.consumedSeedsThisGrid}}visualize(){const t=[],e=[],n=[],s=this.srj??this.input.simpleRouteJson,o=s.bounds.minX,i=s.bounds.maxX,r=s.bounds.minY,a=s.bounds.maxY;s.outline&&s.outline.length>1?n.push({points:[...s.outline,s.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):t.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of s.obstacles??[])"rect"!==e.type&&"oval"!==e.type||t.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});if(this.boardVoidRects){let e=null;if(s.outline&&s.outline.length>0){const t=s.outline.map(t=>t.x),n=s.outline.map(t=>t.y),o=Math.min(...t),i=Math.min(...n);e={x:o,y:i,width:Math.max(...t)-o,height:Math.max(...n)-i}}for(const n of this.boardVoidRects)e&&!Lt(n,e)||t.push({center:{x:n.x+n.width/2,y:n.y+n.height/2},width:n.width,height:n.height,fill:"rgba(0, 0, 0, 0.5)",stroke:"none",label:"void"})}if(this.candidates?.length)for(const t of this.candidates)e.push({x:t.x,y:t.y,fill:"#9333ea",stroke:"#6b21a8",label:`z:${t.z}`});if(this.placed?.length)for(const e of this.placed){const n=de(e.zLayers);t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,fill:n.fill,stroke:n.stroke,layer:`z${e.zLayers.join(",")}`,label:`free\nz:${e.zLayers.join(",")}`})}return{title:"RectDiff Grid",coordinateSystem:"cartesian",rects:t,points:e,lines:n}}};var pe=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY,fe=class extends N{constructor(t){super(),this.input=t}placedIndexByLayer=[];_meshNodes=[];_setup(){this.stats={gridIndex:this.input.gridIndex},this.placedIndexByLayer=Array.from({length:this.input.layerCount},()=>new st);for(const t of this.input.placed)for(const e of t.zLayers){const n=this.placedIndexByLayer[e];n&&n.insert(he(t.rect,{zLayers:t.zLayers}))}}_step(){this.solved||(this._stepExpansion(),this.stats.gridIndex=this.input.gridIndex,this.stats.placed=this.input.placed.length,this.input.expansionIndex>=this.input.placed.length&&this.finalizeIfNeeded())}_stepExpansion(){if(this.input.expansionIndex>=this.input.placed.length)return;const t=this.input.expansionIndex,e=this.input.placed[t],n=this.input.options.gridSizes[this.input.options.gridSizes.length-1],s=e.rect,o=se({startX:e.rect.x+e.rect.width/2,startY:e.rect.y+e.rect.height/2,gridSize:n,bounds:this.input.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:0,maxAspectRatio:null,minReq:{width:e.rect.width,height:e.rect.height},zLayers:e.zLayers});if(o){this.input.placed[t]={rect:o,zLayers:e.zLayers};for(const t of e.zLayers){const n=this.placedIndexByLayer[t];n&&(n.remove(he(s,{zLayers:e.zLayers}),pe),n.insert(he(o,{zLayers:e.zLayers})))}le({layerCount:this.input.layerCount,placed:this.input.placed,options:this.input.options,placedIndexByLayer:this.placedIndexByLayer},t)}this.input.expansionIndex+=1}finalizeIfNeeded(){if(this.solved)return;const t=function(t){const e=t.placed.map(t=>({minX:t.rect.x,minY:t.rect.y,maxX:t.rect.x+t.rect.width,maxY:t.rect.y+t.rect.height,zLayers:[...t.zLayers].sort((t,e)=>t-e)})),{zIndexByName:n}=Bt(t.srj),s=new Map;for(const e of t.srj.obstacles??[]){const t=Wt(e);if(!t)continue;const o=e.zLayers?.length&&e.zLayers.length>0?e.zLayers:jt(e,n),i=`${t.x}:${t.y}:${t.width}:${t.height}`;let r=s.get(i);r||(r={rect:t,layers:new Set},s.set(i,r)),o.forEach(t=>r.layers.add(t))}for(const{rect:t,layers:n}of s.values())e.push({minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:Array.from(n).sort((t,e)=>t-e),isObstacle:!0});return e}({placed:this.input.placed,srj:this.input.srj,boardVoidRects:this.input.boardVoidRects});this._meshNodes=function(t){let e=0;const n=[];for(const s of t){const t=Math.max(0,s.maxX-s.minX),o=Math.max(0,s.maxY-s.minY);t<=0||o<=0||0===s.zLayers.length||n.push({capacityMeshNodeId:"cmn_"+e++,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:t,height:o,layer:"top",availableZ:s.zLayers.slice(),_containsObstacle:s.isObstacle,_containsTarget:s.isObstacle})}return n}(t),this.solved=!0}computeProgress(){if(this.solved)return 1;const t=this.input.options.gridSizes.length,e=t/(t+1),n=Math.max(1,this.input.placed.length),s=n?this.input.expansionIndex/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){if(this.solved)return{meshNodes:this._meshNodes};return{meshNodes:this.input.placed.map((t,e)=>({capacityMeshNodeId:`expand-preview-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers.slice(),layer:`z${t.zLayers.join(",")}`}))}}visualize(){const t=[];for(const e of this.input.placed??[])t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,stroke:"rgba(37, 99, 235, 0.9)",fill:"rgba(191, 219, 254, 0.5)",layer:`z${e.zLayers.join(",")}`,label:`expanded\nz:${e.zLayers.join(",")}`});return{title:"RectDiff Expansion",coordinateSystem:"cartesian",rects:t,points:[],lines:[]}}},me=class extends _{rectDiffSeedingSolver;rectDiffExpansionSolver;obstacleIndexByLayer;constructor(t){super(t);const{obstacleIndexByLayer:e}=(t=>{const{srj:e,boardVoidRects:n}=t,{layerNames:s,zIndexByName:o}=Bt(e),i=Math.max(1,s.length,e.layerCount||1),r=(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.minX,e.bounds.maxY,e.bounds.minY,Array.from({length:i},()=>new st)),a=(t,e)=>{const n={...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:[e]};r[e]?.insert(n)};if(e.outline&&e.outline.length>2)for(const t of n??[])for(let e=0;e<i;e++)a(t,e);for(const t of e.obstacles??[]){const e=Wt(t);if(!e)continue;const n=jt(t,o),s=n.filter(t=>t<0||t>=i);if(s.length)throw new Error(`RectDiff: obstacle uses z-layer indices ${s.join(",")} outside 0-${i-1}`);t.zLayers&&0!==t.zLayers.length||!n.length||(t.zLayers=n);for(const t of n)a(e,t)}return{obstacleIndexByLayer:r}})({srj:t.simpleRouteJson,boardVoidRects:t.boardVoidRects});this.obstacleIndexByLayer=e}pipelineDef=[I("rectDiffSeedingSolver",ue,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,obstacleIndexByLayer:t.obstacleIndexByLayer,boardVoidRects:t.inputProblem.boardVoidRects}]),I("rectDiffExpansionSolver",fe,t=>{const e=t.rectDiffSeedingSolver?.getOutput();if(!e)throw new Error("RectDiffSeedingSolver did not produce output");return[{srj:t.inputProblem.simpleRouteJson,layerNames:e.layerNames??[],boardVoidRects:t.inputProblem.boardVoidRects??[],layerCount:t.inputProblem.simpleRouteJson.layerCount,bounds:e.bounds,candidates:e.candidates,consumedSeedsThisGrid:e.placed.length,totalSeedsThisGrid:e.candidates.length,placed:e.placed,edgeAnalysisDone:e.edgeAnalysisDone,gridIndex:e.gridIndex,expansionIndex:e.expansionIndex,obstacleIndexByLayer:t.obstacleIndexByLayer,options:e.options}]})];getConstructorParams(){return[this.inputProblem]}getOutput(){if(this.rectDiffExpansionSolver)return this.rectDiffExpansionSolver.getOutput();if(this.rectDiffSeedingSolver){return{meshNodes:this.rectDiffSeedingSolver.getOutput().placed.map((t,e)=>({capacityMeshNodeId:`grid-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers,layer:`z${t.zLayers.join(",")}`}))}}return{meshNodes:[]}}visualize(){return this.rectDiffExpansionSolver?this.rectDiffExpansionSolver.visualize():this.rectDiffSeedingSolver?this.rectDiffSeedingSolver.visualize():{title:"RectDiff Grid Pipeline",coordinateSystem:"cartesian",rects:[],points:[],lines:[]}}};function ge(t,e="RectDiff"){const n=[],s=[],o=t.bounds.minX,i=t.bounds.maxX,r=t.bounds.minY,a=t.bounds.maxY;t.outline&&t.outline.length>1?s.push({points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):n.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of t.obstacles??[])"rect"!==e.type&&"oval"!==e.type||n.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});return{title:e,coordinateSystem:"cartesian",rects:n,points:[],lines:s}}var ye=class extends _{rectDiffGridSolverPipeline;gapFillSolver;boardVoidRects;pipelineDef=[I("rectDiffGridSolverPipeline",me,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,boardVoidRects:t.boardVoidRects}]),I("gapFillSolver",Tt,t=>[{meshNodes:t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],boardVoid:{boardVoidRects:t.boardVoidRects||[],layerCount:t.inputProblem.simpleRouteJson.layerCount||0}}])];_setup(){this.inputProblem.simpleRouteJson.outline&&(this.boardVoidRects=kt({x:this.inputProblem.simpleRouteJson.bounds.minX,y:this.inputProblem.simpleRouteJson.bounds.minY,width:this.inputProblem.simpleRouteJson.bounds.maxX-this.inputProblem.simpleRouteJson.bounds.minX,height:this.inputProblem.simpleRouteJson.bounds.maxY-this.inputProblem.simpleRouteJson.bounds.minY},this.inputProblem.simpleRouteJson.outline??[]))}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.gapFillSolver?.getOutput();return t?{meshNodes:t.outputNodes}:this.rectDiffGridSolverPipeline?this.rectDiffGridSolverPipeline.getOutput():{meshNodes:[]}}initialVisualize(){const t=ge(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Initial"),e=this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[];for(const n of e)t.rects.push({center:n.center,width:n.width,height:n.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t=ge(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Final"),{meshNodes:e}=this.getOutput(),n=new Set((this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[]).map(t=>t.capacityMeshNodeId));for(const s of e){const e=!n.has(s.capacityMeshNodeId);t.rects.push({center:s.center,width:s.width,height:s.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${s.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${s.capacityMeshNodeId}`,`z:${s.availableZ.join(",")}`].join("\n")})}return t}},xe=class{cacheHitsByPrefix={};cacheMissesByPrefix={};isSyncCache=!0;cacheHits=0;cacheMisses=0;cache=new Map;getCachedSolutionSync(t){const e=this.cache.get(t);if(void 0!==e){this.cacheHits++;const n=t.split(":")[0];return this.cacheHitsByPrefix[n]=(this.cacheHitsByPrefix[n]||0)+1,structuredClone(e)}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){this.cache.set(t,structuredClone(e))}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){this.cache.clear(),this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}getAllCacheKeys(){return Array.from(this.cache.keys())}},ve="tscircuit_autorouter_cache_",be=class{isSyncCache=!0;cacheHits=0;cacheMisses=0;cacheHitsByPrefix={};cacheMissesByPrefix={};constructor(){}getKey(t){return`${ve}${t}`}getCachedSolutionSync(t){if("undefined"==typeof localStorage)return;const e=this.getKey(t);try{const n=localStorage.getItem(e);if(null!==n){const e=JSON.parse(n);this.cacheHits++;const s=t.split(":")[0];return this.cacheHitsByPrefix[s]=(this.cacheHitsByPrefix[s]||0)+1,e}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}catch(n){console.error(`Error getting cached solution sync for ${e}:`,n),this.cacheMisses++;const s=t.split(":")[0];return void(this.cacheMissesByPrefix[s]=(this.cacheMissesByPrefix[s]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){if("undefined"==typeof localStorage)return;const n=this.getKey(t);try{const t=JSON.stringify(e);localStorage.setItem(n,t)}catch(t){console.error(`Error setting cached solution sync for ${n}:`,t),t instanceof DOMException&&("QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)&&console.warn(`LocalStorage quota exceeded. Failed to cache solution for ${n}. Consider clearing the cache.`)}}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){if("undefined"!=typeof localStorage)try{const t=[];for(let e=0;e<localStorage.length;e++){const n=localStorage.key(e);n?.startsWith(ve)&&t.push(n)}t.forEach(t=>localStorage.removeItem(t)),console.log(`Cleared ${t.length} items from LocalStorage cache.`)}catch(t){console.error("Error clearing LocalStorage cache:",t)}finally{this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}}getAllCacheKeys(){const t=[];for(let e=0;e<1e4;e++){const n=localStorage.key(e);if(!n)break;n.includes(ve)&&t.push(n)}return t}};function Pe(){return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE||Me(),globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE}function Se(){return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE||Me(),globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE}function Me(){globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE??=new be,globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE??=new xe}function Ne(t){const e={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};for(const n of t.portPoints)n.x<e.minX&&(e.minX=n.x),n.x>e.maxX&&(e.maxX=n.x),n.y<e.minY&&(e.minY=n.y),n.y>e.maxY&&(e.maxY=n.y);return e}var Ie=(t,e)=>t<=e?[t,e]:[e,t],_e=t=>`${t[0]}|${t[1]}`,Ce=({portPointId:t,currentNodeId:e,inputNodes:n})=>{let s;if(t)for(const e of n){const n=e.portPoints.find(e=>e.portPointId===t);if(n?.connectionNodeIds){s=n.connectionNodeIds;break}}if(!s||2!==s.length)return[e,e];const[o,i]=s;return o&&i?Ie(o,i):[e,e]},Te=1e-6,Ee=(t,e)=>Math.abs(t-e)<=Te,we=({nodeAId:t,nodeBId:e,nodeBounds:n})=>{if(t===e)return null;const s=n.get(t),o=n.get(e);if(!s||!o)return null;const i=Ie(t,e),r=_e(i);if(Ee(s.maxX,o.minX)||Ee(o.maxX,s.minX)){const n=Math.max(s.minY,o.minY),a=Math.min(s.maxY,o.maxY),c=a-n;if(c>Te){const h=Ee(s.maxX,o.minX)?s.maxX:s.minX;return{ownerNodeIds:i,ownerPairKey:r,orientation:"vertical",x1:h,y1:n,x2:h,y2:a,center:{x:h,y:(n+a)/2},length:c,nodeSideByOwnerId:Ee(s.maxX,o.minX)?{[t]:"right",[e]:"left"}:{[t]:"left",[e]:"right"}}}}if(Ee(s.maxY,o.minY)||Ee(o.maxY,s.minY)){const n=Math.max(s.minX,o.minX),a=Math.min(s.maxX,o.maxX),c=a-n;if(c>Te){const h=Ee(s.maxY,o.minY)?s.maxY:s.minY;return{ownerNodeIds:i,ownerPairKey:r,orientation:"horizontal",x1:n,y1:h,x2:a,y2:h,center:{x:(n+a)/2,y:h},length:c,nodeSideByOwnerId:Ee(s.maxY,o.minY)?{[t]:"top",[e]:"bottom"}:{[t]:"bottom",[e]:"top"}}}}return null},Re=({portPoint:t,ownerNodeIds:e,inputNodes:n})=>{for(const s of e){const e=n.find(t=>t.capacityMeshNodeId===s);if(e?._containsTarget)return!0;const o=e?.portPoints.find(e=>e.portPointId===t.portPointId);if(o?.connectionNodeIds?.some(t=>n.find(e=>e.capacityMeshNodeId===t)?._containsTarget))return!0}return!1},Oe=1e-6,Ae=class extends N{constructor(t){super(),this.input=t;for(const e of t.nodeWithPortPoints)this.mapOfNodeIdToBounds.set(e.capacityMeshNodeId,Ne(e));const e=new Map;for(const n of t.nodeWithPortPoints)for(const s of n.portPoints){if(!s.portPointId)continue;const o=Ce({portPointId:s.portPointId,currentNodeId:n.capacityMeshNodeId,inputNodes:t.inputNodesWithPortPoints}),i=_e(o),r=this.mapOfOwnerPairToPortPoints.get(i)??[];r.some(t=>t.portPointId&&t.portPointId===s.portPointId)||r.push({...s,ownerNodeIds:o,ownerPairKey:i}),this.mapOfOwnerPairToPortPoints.set(i,r),e.set(i,o)}this.mapOfOwnerPairToSharedEdge=(({ownerPairs:t,nodeBounds:e})=>{const n=new Map;for(const s of t){const[t,o]=s;if(t===o)continue;const i=we({nodeAId:t,nodeBId:o,nodeBounds:e});i&&n.set(_e(s),i)}return n})({ownerPairs:Array.from(e.values()),nodeBounds:this.mapOfNodeIdToBounds}),this.ownerPairsToProcess=Array.from(this.mapOfOwnerPairToSharedEdge.keys()),this.ownerPairsToProcess.sort((t,e)=>{const n=this.mapOfOwnerPairToSharedEdge.get(t),s=this.mapOfOwnerPairToSharedEdge.get(e);return n.center.x-s.center.x||n.center.y-s.center.y})}getSolverName(){return"UniformPortDistributionSolver"}mapOfNodeIdToBounds=new Map;mapOfOwnerPairToPortPoints=new Map;mapOfOwnerPairToSharedEdge=new Map;ownerPairsToProcess=[];currentOwnerPairBeingProcessed=null;redistributedNodes=[];step(){if(0===this.ownerPairsToProcess.length)return this.rebuildNodes(),void(this.solved=!0);this.currentOwnerPairBeingProcessed=this.ownerPairsToProcess.shift();const t=this.currentOwnerPairBeingProcessed,e=this.mapOfOwnerPairToSharedEdge.get(t);if(!e)return;if((({sharedEdge:t,obstacles:e})=>{for(const n of e){const e=n.center.x-n.width/2,s=n.center.x+n.width/2,o=n.center.y-n.height/2,i=n.center.y+n.height/2;if("vertical"!==t.orientation){if(Math.abs(t.y1-o)<Oe||Math.abs(t.y1-i)<Oe){const n=Math.max(t.x1,e);if(Math.min(t.x2,s)-n>Oe)return!0}}else if(Math.abs(t.x1-e)<Oe||Math.abs(t.x1-s)<Oe){const e=Math.max(t.y1,o);if(Math.min(t.y2,i)-e>Oe)return!0}}return!1})({sharedEdge:e,obstacles:this.input.obstacles}))return;const n=this.mapOfOwnerPairToPortPoints.get(t)??[],s=[];for(const t of n)Re({portPoint:t,ownerNodeIds:t.ownerNodeIds,inputNodes:this.input.inputNodesWithPortPoints})||s.push(t);const o=(({sharedEdge:t,portPoints:e})=>{if(0===e.length)return[];const n=new Map;for(const t of e){const e=t.z??0,s=n.get(e)??[];s.push(t),n.set(e,s)}const s=[],o=Array.from(n.keys()).sort((t,e)=>t-e);for(const e of o){const o=n.get(e),i=o.length;o.sort((e,n)=>"horizontal"===t.orientation?e.x-n.x:e.y-n.y);for(let e=0;e<i;e++){const n=(2*e+1)/(2*i),r="horizontal"===t.orientation?t.x1+t.length*n:t.x1,a="horizontal"===t.orientation?t.y1:t.y1+t.length*n;s.push({...o[e],x:r,y:a})}}return s})({sharedEdge:e,portPoints:s});this.mapOfOwnerPairToPortPoints.set(t,o)}rebuildNodes(){const t=new Map;for(const e of this.mapOfOwnerPairToPortPoints.values())for(const n of e)n.portPointId&&t.set(n.portPointId,{x:n.x,y:n.y});this.redistributedNodes=this.input.nodeWithPortPoints.map(e=>({...e,portPoints:e.portPoints.map(e=>{if(e.portPointId&&t.has(e.portPointId)){const n=t.get(e.portPointId);return{...e,x:n.x,y:n.y}}return e})}))}getOutput=()=>this.redistributedNodes;visualize(){return(({obstacles:t,nodeWithPortPoints:e,mapOfOwnerPairToPortPoints:n,mapOfOwnerPairToSharedEdge:s,ownerPairsToProcess:o,currentOwnerPairBeingProcessed:i,mapOfNodeIdToBounds:r})=>{const a=t.map(t=>({...t,fill:"#ec000070"})),c=[],h=[],l=new Map,d=new Map,u=new Map;for(const t of e)for(const e of t.portPoints)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0));for(const t of n.values())for(const e of t)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0),u.set(e.portPointId,`${e.ownerNodeIds[0]}&${e.ownerNodeIds[1]}`));e.forEach(t=>{const e=r.get(t.capacityMeshNodeId);if(e){const n=(e.minX+e.maxX)/2,s=(e.minY+e.maxY)/2,o=e.maxX-e.minX,i=e.maxY-e.minY;a.push({center:{x:n,y:s},width:o,height:i,fill:"#00000030",label:`${t.capacityMeshNodeId}`})}t.portPoints.forEach(e=>{if(!e.portPointId)return;const n=l.get(e.portPointId),s=d.get(e.portPointId)??0,o=u.get(e.portPointId)??`${t.capacityMeshNodeId}&${t.capacityMeshNodeId}`;c.push({x:n.x,y:n.y,label:`z:${s}\no:${o}`}),t.portPoints.forEach(t=>{if(t.portPointId&&e!==t&&e.connectionName===t.connectionName){const e=l.get(t.portPointId);h.push({points:[n,e],strokeColor:"#fff822c9"})}})})});for(const t of o){const e=s.get(t);e&&h.push({points:[{x:e.x1,y:e.y1},{x:e.x2,y:e.y2}],strokeColor:"orange",strokeWidth:.01})}if(i){const t=s.get(i);t&&(h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"red",strokeWidth:.03}),c.push({x:t.center.x,y:t.center.y,label:t.ownerPairKey}))}for(const t of s.values())h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"#33b5ff80",strokeWidth:.006});return{rects:a,lines:h,points:c}})({obstacles:this.input.obstacles,nodeWithPortPoints:this.input.nodeWithPortPoints,mapOfOwnerPairToPortPoints:this.mapOfOwnerPairToPortPoints,mapOfOwnerPairToSharedEdge:this.mapOfOwnerPairToSharedEdge,ownerPairsToProcess:this.ownerPairsToProcess,currentOwnerPairBeingProcessed:this.currentOwnerPairBeingProcessed,mapOfNodeIdToBounds:this.mapOfNodeIdToBounds})}},ze=(t,e)=>{if(1===t&&1===e)return"inner1";if(t<0||t>=e)throw new Error(`Invalid z "${t}" for layer count: ${e}`);return 0===t?"top":t===e-1?"bottom":`inner${t}`},Le=(t,e)=>{const n=[];if(0===t.route.length)return n;let s=[],o=t.route[0].z;for(let i=0;i<t.route.length;i++){const r=t.route[i];if(r.z!==o){const i=ze(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.vias.some(t=>Math.abs(t.x-r.x)<.001&&Math.abs(t.y-r.y)<.001)){const t=ze(o,e),s=ze(r.z,e);n.push({route_type:"via",x:r.x,y:r.y,from_layer:t,to_layer:s})}s=[r],o=r.z}else s.push(r)}const i=ze(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.jumpers&&t.jumpers.length>0){const s=ze(t.route[0]?.z??0,e);for(const e of t.jumpers)n.push({route_type:"jumper",start:e.start,end:e.end,footprint:e.footprint,layer:s})}return n};function De(){return De=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var s in n)({}).hasOwnProperty.call(n,s)&&(t[s]=n[s])}return t},De.apply(null,arguments)}function Fe(t,e){return(Fe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function Ye(t){return(Ye=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function Xe(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(Xe=function(){return!!t})()}function ke(t){var e="function"==typeof Map?new Map:void 0;return ke=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(Xe())return Reflect.construct.apply(null,arguments);var s=[null];s.push.apply(s,e);var o=new(t.bind.apply(t,s));return n&&Fe(o,n.prototype),o}(t,arguments,Ye(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),Fe(n,t)},ke(t)}var $e={1:"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\n\n",2:"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\n\n",3:"Passed an incorrect argument to a color function, please pass a string representation of a color.\n\n",4:"Couldn't generate valid rgb string from %s, it returned %s.\n\n",5:"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\n\n",6:"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\n\n",7:"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\n\n",8:"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\n\n",9:"Please provide a number of steps to the modularScale helper.\n\n",10:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",11:'Invalid value passed as base to modularScale, expected number or em string but got "%s"\n\n',12:'Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.\n\n',13:'Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.\n\n',14:'Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',15:'Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',16:"You must provide a template to this method.\n\n",17:"You passed an unsupported selector state to this method.\n\n",18:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",19:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",20:"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",21:"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n",22:"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n",23:"fontFace expects a name of a font-family.\n\n",24:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",25:"fontFace expects localFonts to be an array.\n\n",26:"fontFace expects fileFormats to be an array.\n\n",27:"radialGradient requries at least 2 color-stops to properly render.\n\n",28:"Please supply a filename to retinaImage() as the first argument.\n\n",29:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",30:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",31:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\n\n",32:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\n\n",33:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\n\n",34:"borderRadius expects a radius value as a string or number as the second argument.\n\n",35:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',36:"Property must be a string value.\n\n",37:"Syntax Error at %s.\n\n",38:"Formula contains a function that needs parentheses at %s.\n\n",39:"Formula is missing closing parenthesis at %s.\n\n",40:"Formula has too many closing parentheses at %s.\n\n",41:"All values in a formula must have the same unit or be unitless.\n\n",42:"Please provide a number of steps to the modularScale helper.\n\n",43:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",44:"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\n\n",45:"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\n\n",46:"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\n\n",47:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",48:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",49:"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",50:"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\n\n",51:"Expects the first argument object to have the properties prop, fromSize, and toSize.\n\n",52:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",53:"fontFace expects localFonts to be an array.\n\n",54:"fontFace expects fileFormats to be an array.\n\n",55:"fontFace expects a name of a font-family.\n\n",56:"linearGradient requries at least 2 color-stops to properly render.\n\n",57:"radialGradient requries at least 2 color-stops to properly render.\n\n",58:"Please supply a filename to retinaImage() as the first argument.\n\n",59:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",60:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",61:"Property must be a string value.\n\n",62:"borderRadius expects a radius value as a string or number as the second argument.\n\n",63:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',64:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\n\n",65:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\n\n",66:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\n\n",67:"You must provide a template to this method.\n\n",68:"You passed an unsupported selector state to this method.\n\n",69:'Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.\n\n',70:'Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.\n\n',71:'Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.\n\n',72:'Passed invalid base value %s to %s(), please pass a value like "12px" or 12.\n\n',73:"Please provide a valid CSS variable.\n\n",74:"CSS variable not found and no default was provided.\n\n",75:"important requires a valid style object, got a %s instead.\n\n",76:"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n\n",77:'remToPx expects a value in "rem" but you provided it in "%s".\n\n',78:'base must be set in "px" or "%" but you set it in "%s".\n'};function Be(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var s,o=e[0],i=[];for(s=1;s<e.length;s+=1)i.push(e[s]);return i.forEach(function(t){o=o.replace(/%[a-z]/,t)}),o}var je=function(t){var e,n;function s(e){var n;if("production"===process.env.NODE_ENV)n=t.call(this,"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#"+e+" for more information.")||this;else{for(var s=arguments.length,o=new Array(s>1?s-1:0),i=1;i<s;i++)o[i-1]=arguments[i];n=t.call(this,Be.apply(void 0,[$e[e]].concat(o)))||this}return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)}return n=t,(e=s).prototype=Object.create(n.prototype),e.prototype.constructor=e,Fe(e,n),s}(ke(Error));function We(t,e){return t.substr(-e.length)===e}var He=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function Ue(t){return"string"!=typeof t?t:t.match(He)?parseFloat(t):t}var Ve=function(t){return function(e,n){void 0===n&&(n="16px");var s=e,o=n;if("string"==typeof e){if(!We(e,"px"))throw new je(69,t,e);s=Ue(e)}if("string"==typeof n){if(!We(n,"px"))throw new je(70,t,n);o=Ue(n)}if("string"==typeof s)throw new je(71,e,t);if("string"==typeof o)throw new je(72,n,t);return""+s/o+t}};Ve("em"),Ve("rem");function Ge(t){return Math.round(255*t)}function Ze(t,e,n){return Ge(t)+","+Ge(e)+","+Ge(n)}function qe(t,e,n,s){if(void 0===s&&(s=Ze),0===e)return s(n,n,n);var o=(t%360+360)%360/60,i=(1-Math.abs(2*n-1))*e,r=i*(1-Math.abs(o%2-1)),a=0,c=0,h=0;o>=0&&o<1?(a=i,c=r):o>=1&&o<2?(a=r,c=i):o>=2&&o<3?(c=i,h=r):o>=3&&o<4?(c=r,h=i):o>=4&&o<5?(a=r,h=i):o>=5&&o<6&&(a=i,h=r);var l=n-i/2;return s(a+l,c+l,h+l)}var Je={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"639",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"};var Ke=/^#[a-fA-F0-9]{6}$/,Qe=/^#[a-fA-F0-9]{8}$/,tn=/^#[a-fA-F0-9]{3}$/,en=/^#[a-fA-F0-9]{4}$/,nn=/^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i,sn=/^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i,on=/^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i,rn=/^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;function an(t){if("string"!=typeof t)throw new je(3);var e=function(t){if("string"!=typeof t)return t;var e=t.toLowerCase();return Je[e]?"#"+Je[e]:t}(t);if(e.match(Ke))return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16)};if(e.match(Qe)){var n=parseFloat((parseInt(""+e[7]+e[8],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16),alpha:n}}if(e.match(tn))return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16)};if(e.match(en)){var s=parseFloat((parseInt(""+e[4]+e[4],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16),alpha:s}}var o=nn.exec(e);if(o)return{red:parseInt(""+o[1],10),green:parseInt(""+o[2],10),blue:parseInt(""+o[3],10)};var i=sn.exec(e.substring(0,50));if(i)return{red:parseInt(""+i[1],10),green:parseInt(""+i[2],10),blue:parseInt(""+i[3],10),alpha:parseFloat(""+i[4])>1?parseFloat(""+i[4])/100:parseFloat(""+i[4])};var r=on.exec(e);if(r){var a="rgb("+qe(parseInt(""+r[1],10),parseInt(""+r[2],10)/100,parseInt(""+r[3],10)/100)+")",c=nn.exec(a);if(!c)throw new je(4,e,a);return{red:parseInt(""+c[1],10),green:parseInt(""+c[2],10),blue:parseInt(""+c[3],10)}}var h=rn.exec(e.substring(0,50));if(h){var l="rgb("+qe(parseInt(""+h[1],10),parseInt(""+h[2],10)/100,parseInt(""+h[3],10)/100)+")",d=nn.exec(l);if(!d)throw new je(4,e,l);return{red:parseInt(""+d[1],10),green:parseInt(""+d[2],10),blue:parseInt(""+d[3],10),alpha:parseFloat(""+h[4])>1?parseFloat(""+h[4])/100:parseFloat(""+h[4])}}throw new je(5)}function cn(t){return function(t){var e,n=t.red/255,s=t.green/255,o=t.blue/255,i=Math.max(n,s,o),r=Math.min(n,s,o),a=(i+r)/2;if(i===r)return void 0!==t.alpha?{hue:0,saturation:0,lightness:a,alpha:t.alpha}:{hue:0,saturation:0,lightness:a};var c=i-r,h=a>.5?c/(2-i-r):c/(i+r);switch(i){case n:e=(s-o)/c+(s<o?6:0);break;case s:e=(o-n)/c+2;break;default:e=(n-s)/c+4}return e*=60,void 0!==t.alpha?{hue:e,saturation:h,lightness:a,alpha:t.alpha}:{hue:e,saturation:h,lightness:a}}(an(t))}var hn=function(t){return 7===t.length&&t[1]===t[2]&&t[3]===t[4]&&t[5]===t[6]?"#"+t[1]+t[3]+t[5]:t};function ln(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function dn(t){return ln(Math.round(255*t))}function un(t,e,n){return hn("#"+dn(t)+dn(e)+dn(n))}function pn(t,e,n){return qe(t,e,n,un)}function fn(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return hn("#"+ln(t)+ln(e)+ln(n));if("object"==typeof t&&void 0===e&&void 0===n)return hn("#"+ln(t.red)+ln(t.green)+ln(t.blue));throw new je(6)}function mn(t,e,n,s){if("string"==typeof t&&"number"==typeof e){var o=an(t);return"rgba("+o.red+","+o.green+","+o.blue+","+e+")"}if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?fn(t,e,n):"rgba("+t+","+e+","+n+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?fn(t.red,t.green,t.blue):"rgba("+t.red+","+t.green+","+t.blue+","+t.alpha+")";throw new je(7)}function gn(t){if("object"!=typeof t)throw new je(8);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&"number"==typeof t.alpha}(t))return mn(t);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return fn(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&"number"==typeof t.alpha}(t))return function(t,e,n,s){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?pn(t,e,n):"rgba("+qe(t,e,n)+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?pn(t.hue,t.saturation,t.lightness):"rgba("+qe(t.hue,t.saturation,t.lightness)+","+t.alpha+")";throw new je(2)}(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return function(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return pn(t,e,n);if("object"==typeof t&&void 0===e&&void 0===n)return pn(t.hue,t.saturation,t.lightness);throw new je(1)}(t);throw new je(8)}function yn(t,e,n){return function(){var s=n.concat(Array.prototype.slice.call(arguments));return s.length>=e?t.apply(this,s):yn(t,e,s)}}function xn(t){return yn(t,t.length,[])}xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(De({},n,{hue:n.hue+parseFloat(t)}))});function vn(t,e,n){return Math.max(t,Math.min(e,n))}xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(De({},n,{lightness:vn(0,1,n.lightness-parseFloat(t))}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(De({},n,{saturation:vn(0,1,n.saturation-parseFloat(t))}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(De({},n,{lightness:vn(0,1,n.lightness+parseFloat(t))}))});var bn=xn(function(t,e,n){if("transparent"===e)return n;if("transparent"===n)return e;if(0===t)return n;var s=an(e),o=De({},s,{alpha:"number"==typeof s.alpha?s.alpha:1}),i=an(n),r=De({},i,{alpha:"number"==typeof i.alpha?i.alpha:1}),a=o.alpha-r.alpha,c=2*parseFloat(t)-1,h=((c*a===-1?c:c+a)/(1+c*a)+1)/2,l=1-h;return mn({red:Math.floor(o.red*h+r.red*l),green:Math.floor(o.green*h+r.green*l),blue:Math.floor(o.blue*h+r.blue*l),alpha:o.alpha*parseFloat(t)+r.alpha*(1-parseFloat(t))})});xn(function(t,e){if("transparent"===e)return e;var n=an(e);return mn(De({},n,{alpha:vn(0,1,(100*("number"==typeof n.alpha?n.alpha:1)+100*parseFloat(t))/100)}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(De({},n,{saturation:vn(0,1,n.saturation+parseFloat(t))}))});xn(function(t,e){return"transparent"===e?e:gn(De({},cn(e),{hue:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:gn(De({},cn(e),{lightness:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:gn(De({},cn(e),{saturation:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:bn(parseFloat(t),"rgb(0, 0, 0)",e)});xn(function(t,e){return"transparent"===e?e:bn(parseFloat(t),"rgb(255, 255, 255)",e)});var Pn=xn(function(t,e){if("transparent"===e)return e;var n=an(e);return mn(De({},n,{alpha:vn(0,1,+(100*("number"==typeof n.alpha?n.alpha:1)-100*parseFloat(t)).toFixed(2)/100)}))}),Sn=["blue","orange","purple","cyan","magenta","yellowgreen","darkgoldenrod","deeppink"],Mn=(t,e)=>{const n={};for(let s=0;s<t.connections.length;s++){const o=t.connections[s],i=e?.getNetConnectedToId(o.name);i&&!n[i]&&(n[i]=`hsl(${300*s/t.connections.length}, 100%, 50%)`),n[o.name]=(i?n[i]:null)??`hsl(${340*s/t.connections.length}, 100%, 50%)`}return n},Nn=(t,e)=>{try{return Pn(e,t)}catch(e){return console.error(e),t}},In=(t,e=1)=>{if(!t)return"rgba(0, 0, 0, 0.5)";const n=300*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)/t.length;return e<1?`hsla(${n}, 100%, 50%, ${e})`:`hsl(${n}, 100%, 50%)`};function _n(t){return"layers"in t&&Array.isArray(t.layers)}function Cn(t){return _n(t)?t.layers[0]:t.layer}function Tn(t){return _n(t)?t.layers:[t.layer]}var En={"0603":{length:1.65,width:.95,padLength:.8,padWidth:.95},1206:{length:3.2,width:1.6,padLength:.6,padWidth:1.6},"1206x4_pair":{length:2.7,width:.5,padLength:.8,padWidth:.5}},wn=(t,e)=>"top"===t?0:"bottom"===t?e-1:parseInt(t.slice(5)),Rn=t=>{const e=[],n=[],s=[],o=[],i=Mn(t),r=(t.minViaDiameter??.3)/2;if(t.connections)for(const e of t.connections)for(const t of e.pointsToConnect){const n=Tn(t);s.push({x:t.x,y:t.y,color:i[e.name],layer:n[0]??("z"in t?ze(t.z,2):"top"),label:`${e.name} (${n.join(",")})`})}if(t.traces)for(const s of t.traces){let a=t.minTraceWidth;const c=s.route.filter(t=>"jumper"===t.route_type),h=(t,e)=>{const n=.01;for(const s of c){const o=Math.abs(t.x-s.start.x)<n&&Math.abs(t.y-s.start.y)<n&&Math.abs(e.x-s.end.x)<n&&Math.abs(e.y-s.end.y)<n,i=Math.abs(t.x-s.end.x)<n&&Math.abs(t.y-s.end.y)<n&&Math.abs(e.x-s.start.x)<n&&Math.abs(e.y-s.start.y)<n;if(o||i)return!0}return!1};for(let t=0;t<s.route.length-1;t++){const c=s.route[t],l=s.route[t+1];if("via"===c.route_type)n.push({center:{x:c.x,y:c.y},radius:r,fill:"blue",stroke:"none",layer:"z0,1"});else if("jumper"===c.route_type){const t=i[s.connection_name]??"rgba(255, 165, 0, 0.8)",n=c.footprint,r=En["1206x4_pair"===n?"1206x4_pair":"0603"]??En["0603"],a=c.end.x-c.start.x,h=c.end.y-c.start.y,l=Math.abs(a)>Math.abs(h),d=l?r.padLength:r.padWidth,u=l?r.padWidth:r.padLength;o.push({center:c.start,width:d,height:u,fill:Nn(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),o.push({center:c.end,width:d,height:u,fill:Nn(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),e.push({points:[c.start,c.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"})}else if("wire"===c.route_type&&"wire"===l.route_type&&l.layer===c.layer){if(h({x:c.x,y:c.y},{x:l.x,y:l.y}))continue;a=c.width;const t=i[s.connection_name],n="top"===c.layer,o=t??{top:"red",bottom:"blue",inner1:"green",inner2:"yellow"}[c.layer];e.push({points:[{x:c.x,y:c.y},{x:l.x,y:l.y}],layer:`z${wn(c.layer,2)}`,strokeWidth:a,strokeColor:n?o:Nn(o,.5),...n?{}:{strokeDash:"3 2"}})}}}for(const e of t.obstacles)o.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255,0,0,0.5)",layer:`z${e.layers.map(t=>wn(t,2)).join(",")}`});if(t.jumpers)for(const e of t.jumpers)for(const t of e.pads)o.push({center:t.center,width:t.width,height:t.height,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:"jumper"});return{rects:o,circles:n,lines:e,points:s}},On=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){this.netMap[n].push(...this.netMap[e]),this.netMap[e]=this.netMap[n];for(const t of this.netMap[n])this.idToNetMap[t]=n}}for(const t of e)this.netMap[n].includes(t)||this.netMap[n].push(t),this.idToNetMap[t]=n}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){const e=this.getNetConnectedToId(t[0]);for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}},An=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)}`,zn=t=>{const e=new On({});for(const n of t.connections){if(n.rootConnectionName&&e.addConnections([[n.name,n.rootConnectionName]]),n.netConnectionName&&e.addConnections([[n.name,n.netConnectionName]]),n.mergedConnectionNames)for(const t of n.mergedConnectionNames)e.addConnections([[n.name,t]]);for(const s of n.pointsToConnect)e.addConnections([[n.name,`${An(s)}:${"layers"in s?s.layers.map(e=>wn(e,t.layerCount)).sort().join("-"):wn(s.layer,t.layerCount)}`]]),"pcb_port_id"in s&&s.pcb_port_id&&e.addConnections([[n.name,s.pcb_port_id]])}for(const n of t.obstacles){const s=n.offBoardConnectsTo??[],o=Array.from(new Set([n.obstacleId,...n.connectedTo,...s,`${An(n.center)}:${n.layers.map(e=>wn(e,t.layerCount)).sort().join("-")}`].filter(Boolean)));o.length>0&&e.addConnections([o])}return e},Ln=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};cacheHit;cacheKey;cacheToSolveSpaceTransform;getSolverName(){return this.constructor.name}step(){if(!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,console.error(this.error),this.failed=!0,t}!this.solved&&this.iterations>this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations (MAX_ITERATIONS=${this.MAX_ITERATIONS})`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Dn(t){const e=new Map;for(const n of t)for(const t of n.nodeIds)e.set(t,[...e.get(t)??[],n]);return e}var Fn=class extends Ln{getSolverName(){return"AvailableSegmentPointSolver"}nodes;edges;traceWidth;obstacleMargin;minPortSpacing;nodeMap;nodeEdgeMap;sharedEdgeSegments=[];edgeSegmentMap=new Map;portPointMap=new Map;colorMap;shouldReturnCrampedPortPoints;constructor({nodes:t,edges:e,traceWidth:n,obstacleMargin:s,colorMap:o,shouldReturnCrampedPortPoints:i}){super(),this.nodes=t,this.edges=e,this.traceWidth=n,this.obstacleMargin=s??.15,this.shouldReturnCrampedPortPoints=i,this.minPortSpacing=this.traceWidth+this.obstacleMargin,this.colorMap=o??{},this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Dn(e),this.MAX_ITERATIONS=1}_step(){this.computeAllSharedEdgeSegments(),this.solved=!0}computeAllSharedEdgeSegments(){for(const t of this.edges){const[e,n]=t.nodeIds,s=this.nodeMap.get(e),o=this.nodeMap.get(n);if(!s||!o)continue;const i=this.computeSharedEdgeSegment(t,s,o);if(i){this.sharedEdgeSegments.push(i),this.edgeSegmentMap.set(t.capacityMeshEdgeId,i);for(const t of i.portPoints)this.portPointMap.set(t.segmentPortPointId,t)}}}computeSharedEdgeSegment(t,e,n){const s=this.findOverlappingSegment(e,n);if(!s)return null;const o=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===o.length)return null;const i=Math.sqrt((s.end.x-s.start.x)**2+(s.end.y-s.start.y)**2),r=3*this.minPortSpacing/4,a=Math.max(0,i-2*r);if(a<=0&&!e._containsTarget&&!n._containsTarget){if(!this.shouldReturnCrampedPortPoints)return null;const i=[];for(const r of o)i.push({segmentPortPointId:`${t.capacityMeshEdgeId}_pp0_z${r}_cramped`,x:(s.start.x+s.end.x)/2,y:(s.start.y+s.end.y)/2,availableZ:[r],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:0,cramped:!0});return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:i}}let c=Math.max(1,Math.floor(a/this.minPortSpacing)+1);if(e._offBoardConnectionId||n._offBoardConnectionId){if(e._offBoardConnectionId&&!n._offBoardConnectionId){if(this.shouldSkipOffBoardPortPoint(e,n))return null}else if(n._offBoardConnectionId&&!e._offBoardConnectionId&&this.shouldSkipOffBoardPortPoint(n,e))return null;c=1}const h=[],l=s.end.x-s.start.x,d=s.end.y-s.start.y,u=(s.start.x+s.end.x)/2,p=(s.start.y+s.end.y)/2;c>5&&(c=5+Math.floor(c/4));const f=[];for(let t=0;t<c;t++){let e;e=0===i||1===c?.5:(r+a*t/(c-1))/i;const n=s.start.x+l*e,o=s.start.y+d*e,h=Math.sqrt((n-u)**2+(o-p)**2);f.push({x:n,y:o,distToCenter:h})}const m=f.reduce((t,e)=>e.distToCenter<t.distToCenter?e:t);for(let s=0;s<c;s++){const{x:i,y:r}=f[s],a=Math.sqrt((i-m.x)**2+(r-m.y)**2);for(const c of o){const o={segmentPortPointId:`${t.capacityMeshEdgeId}_pp${s}_z${c}`,x:i,y:r,availableZ:[c],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:a,cramped:!1};h.push(o)}}return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:h}}shouldSkipOffBoardPortPoint(t,e){const n=this.nodeEdgeMap.get(e.capacityMeshNodeId)??[];for(const s of n){const n=s.nodeIds[0]===e.capacityMeshNodeId?s.nodeIds[1]:s.nodeIds[0];if(n===t.capacityMeshNodeId)continue;const o=this.nodeMap.get(n);if(o?._offBoardConnectionId!==t._offBoardConnectionId)continue;if(2!==this.nodes.filter(e=>e._offBoardConnectionId===t._offBoardConnectionId).length)continue;const i={x:(t.center.x+o.center.x)/2,y:(t.center.y+o.center.y)/2};if(i.x>=e.center.x-e.width/2&&i.x<=e.center.x+e.width/2&&i.y>=e.center.y-e.height/2&&i.y<=e.center.y+e.height/2)return!0}return!1}findOverlappingSegment(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)},o=n.end-n.start,i=s.end-s.start;if(o<-1e-4||i<-1e-4)return null;if(o<i){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}getAvailablePortPointsBetweenNodes(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?s.portPoints.filter(t=>null===t.connectionName):[]}getPortPointsForEdge(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?.portPoints??[]}assignPortPoint(t,e,n){const s=this.portPointMap.get(t);return!!s&&(null===s.connectionName&&(s.connectionName=e,s.rootConnectionName=n,!0))}releasePortPoint(t){const e=this.portPointMap.get(t);return!!e&&(e.connectionName=null,e.rootConnectionName=void 0,!0)}getAvailablePortCountForEdge(t,e){return this.getAvailablePortPointsBetweenNodes(t,e).length}getOutput(){return this.sharedEdgeSegments}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.sharedEdgeSegments){t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.5)"});for(const n of e.portPoints){const e=n.connectionName?this.colorMap[n.connectionName]??"blue":"rgba(0, 200, 0, 0.7)";n.cramped?t.rects.push({center:{x:n.x,y:n.y},width:.1,height:.1,fill:e,layer:`z${n.availableZ.join(",")}`,label:`cramped ${n.segmentPortPointId}`}):t.circles.push({center:{x:n.x,y:n.y},radius:this.traceWidth/2,fill:e,layer:`z${n.availableZ.join(",")}`,label:[n.segmentPortPointId,n.connectionName,n.availableZ.join(","),`cd: ${n.distToCentermostPortOnZ}`,`connects: ${n.nodeIds.join(",")}`].filter(Boolean).join("\n")})}}return t}};function Yn(t,e){const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=e.center.x-e.width/2,a=e.center.x+e.width/2,c=e.center.y-e.height/2,h=e.center.y+e.height/2,l=.001,d=(Math.abs(s-r)<l||Math.abs(n-a)<l)&&Math.min(i,h)-Math.max(o,c)>=l,u=(Math.abs(i-c)<l||Math.abs(o-h)<l)&&Math.min(s,a)-Math.max(n,r)>=l;return d||u}var Xn=class extends Ln{constructor(t){super(),this.nodes=t,this.edges=[]}getSolverName(){return"CapacityMeshEdgeSolver"}edges;nodeMap;getNextCapacityMeshEdgeId(){return`ce${this.edges.length}`}_step(){this.edges=[];for(let t=0;t<this.nodes.length;t++)for(let e=t+1;e<this.nodes.length;e++){!(this.nodes[t]._strawNode&&this.nodes[e]._strawNode&&this.nodes[t]._strawParentCapacityMeshNodeId===this.nodes[e]._strawParentCapacityMeshNodeId)&&Yn(this.nodes[t],this.nodes[e])&&this.doNodesHaveSharedLayer(this.nodes[t],this.nodes[e])&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[this.nodes[t].capacityMeshNodeId,this.nodes[e].capacityMeshNodeId]})}this.handleTargetNodes(),this.solved=!0}handleTargetNodes(){const t=this.nodes.filter(t=>t._containsTarget);for(const e of t){if(this.edges.some(t=>t.nodeIds.includes(e.capacityMeshNodeId)))continue;let t=null,n=1/0;for(const s of this.nodes){if(s._containsObstacle)continue;if(s._containsTarget)continue;const o=k(e.center,s.center);o<n&&(n=o,t=s)}t&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[e.capacityMeshNodeId,t.capacityMeshNodeId]})}}doNodesHaveSharedLayer(t,e){return t.availableZ.some(t=>e.availableZ.includes(t))}visualize(){const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const t=Math.min(...n.availableZ),o=Math.min(...s.availableZ),i={x:n.center.x+t*n.width*.05,y:n.center.y-t*n.width*.05},r={x:s.center.x+o*s.width*.05,y:s.center.y-o*s.width*.05},a=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${a.join(",")}`,points:[i,r],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5"})}}return e}},kn=class{constructor(t){this.nodes=t,this.buckets=new Map;for(const e of t){const t=e.center.x-e.width/2,n=e.center.y-e.height/2,s=e.center.x+e.width/2,o=e.center.y+e.height/2;for(let i=t;i<=s;i+=this.CELL_SIZE)for(let t=n;t<=o;t+=this.CELL_SIZE){const n=this.getBucketKey(i,t),s=this.buckets.get(n);s?s.push(e):this.buckets.set(n,[e])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t.capacityMeshNodeId)||(i.add(t.capacityMeshNodeId),o.push(t))}return o}},$n=class extends Xn{constructor(t){super(t),this.nodes=t,this.MAX_ITERATIONS=1e7,this.nodeTree=new kn(this.nodes),this.currentNodeIndex=0,this.edgeSet=new Set}getSolverName(){return"CapacityMeshEdgeSolver2_NodeTreeOptimization"}nodeTree;currentNodeIndex;edgeSet;_step(){if(this.currentNodeIndex>=this.nodes.length)return this.handleTargetNodes(),void(this.solved=!0);const t=this.nodes[this.currentNodeIndex],e=this.nodeTree.getNodesInArea(t.center.x,t.center.y,2*t.width,2*t.height);for(const n of e){if(!Yn(t,n))continue;const e=t._strawNode&&n._strawNode&&t._strawParentCapacityMeshNodeId===n._strawParentCapacityMeshNodeId;t.capacityMeshNodeId===n.capacityMeshNodeId||e||!this.doNodesHaveSharedLayer(t,n)||this.edgeSet.has(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`)||(this.edgeSet.add(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`),this.edgeSet.add(`${n.capacityMeshNodeId}-${t.capacityMeshNodeId}`),this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[t.capacityMeshNodeId,n.capacityMeshNodeId]}))}this.currentNodeIndex++}},Bn=(...t)=>{const e={points:[],lines:[],circles:[],rects:[]};return t.forEach((t,n)=>{t&&(t.lines&&(e.lines=[...e.lines||[],...t.lines.map(t=>({...t,step:n}))]),t.points&&(e.points=[...e.points||[],...t.points.map(t=>({...t,step:n}))]),t.circles&&(e.circles=[...e.circles||[],...t.circles.map(t=>({...t,step:n}))]),t.rects&&(e.rects=[...e.rects||[],...t.rects.map(t=>({...t,step:n}))]))}),e};function jn(t,e,n){const s=[];let o=null;for(let i=0;i<t.length;i++){const r=t[i];o?o.z===r.z?o.points.push({x:r.x,y:r.y}):(s.push(o),o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n}):o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n},i===t.length-1&&o&&s.push(o)}return s}import Wn from"object-hash";function Hn(t){let e=t;for(let t=0;t<10;t++)e=16807*e%2147483647;let n=e;e=(69069*t+1)%2147483647;for(let t=0;t<10;t++)e=48271*e%2147483647;let s=e;return()=>{let t=n;n=s,t^=t<<23,t^=t>>>17,t^=s,t^=s>>>26,s=t;const e=(n+s)/4294967296;return e-Math.floor(e)}}var Un={1:[[0]],2:[[0,1],[1,0]],3:[[0,1,2],[2,0,1],[1,0,2],[0,2,1],[1,2,0],[2,1,0]],4:[[0,1,2,3],[2,0,1,3],[1,3,2,0],[3,0,1,2],[0,2,1,3],[2,1,3,0],[3,0,2,1],[1,2,0,3],[3,1,0,2],[0,3,2,1],[2,3,0,1],[2,3,1,0],[1,2,3,0],[3,1,2,0],[0,1,3,2],[0,2,3,1],[0,3,1,2],[1,0,2,3],[1,0,3,2],[1,3,0,2],[2,0,3,1],[2,1,0,3],[3,2,0,1],[3,2,1,0]]};function Vn(t,e){if(0===e)return t;if(0===t.length)return t;if(t.length<=4){const n=Un[t.length];return n[e%n.length].map(e=>t[e])}const n=Hn(e),s=t.slice();for(let t=0;t<s.length;t++){const e=Math.floor(n()*s.length),o=Math.floor(n()*(t+1));[s[e],s[o]]=[s[o],s[e]]}return s}var Gn=t=>{let e=1/0;const n=t.portPoints;for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];if(o.z!==i.z)continue;if(o.rootConnectionName&&o.rootConnectionName===i.rootConnectionName)continue;const r=Math.sqrt((o.x-i.x)**2+(o.y-i.y)**2);e=Math.min(e,r)}return e===1/0?0:e},Zn=class{heap=[];constructor(t){this.heap=[];for(const e of t)this.enqueue(e)}getLeftChildIndex(t){return 2*t+1}getRightChildIndex(t){return 2*t+2}getParentIndex(t){return Math.floor((t-1)/2)}hasLeftChild(t){return this.getLeftChildIndex(t)<this.heap.length}hasRightChild(t){return this.getRightChildIndex(t)<this.heap.length}hasParent(t){return this.getParentIndex(t)>=0}leftChild(t){return this.heap[this.getLeftChildIndex(t)]}rightChild(t){return this.heap[this.getRightChildIndex(t)]}parent(t){return this.heap[this.getParentIndex(t)]}swap(t,e){const n=this.heap[t];this.heap[t]=this.heap[e],this.heap[e]=n}dequeue(){if(0===this.heap.length)return null;const t=this.heap[0];return this.heap[0]=this.heap[this.heap.length-1],this.heap.pop(),this.heapifyDown(),t}peek(){return 0===this.heap.length?null:this.heap[0]}enqueue(t){this.heap.push(t),this.heapifyUp()}heapifyUp(){let t=this.heap.length-1;for(;this.hasParent(t)&&this.parent(t).f>this.heap[t].f;)this.swap(this.getParentIndex(t),t),t=this.getParentIndex(t)}heapifyDown(){let t=0;for(;this.hasLeftChild(t);){let e=this.getLeftChildIndex(t);if(this.hasRightChild(t)&&this.rightChild(t).f<this.leftChild(t).f&&(e=this.getRightChildIndex(t)),this.heap[t].f<this.heap[e].f)break;this.swap(t,e),t=e}}getTopN(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}},qn=class extends Ln{getSolverName(){return"SingleHighDensityRouteSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;straightLineDistance;viaDiameter;traceThickness;obstacleMargin;layerCount;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;VIA_PENALTY_FACTOR=.3;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{},this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.obstacleRoutes=t.obstacleRoutes,this.A=t.A,this.B=t.B,this.viaDiameter=t.viaDiameter??.3,this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.layerCount=t.layerCount??2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length;const e=Math.ceil(5*(this.numRoutes+1));let n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;for(;n*s>e**2&&!(2*this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const o=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!o&&this.handleSimpleCases();const i={x:Math.round(t.A.x/(this.cellStep/2))*(this.cellStep/2),y:Math.round(t.A.y/(this.cellStep/2))*(this.cellStep/2)};this.initialNodeGridOffset={x:i.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:i.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.candidates=new Zn([{...t.A,...i,z:t.A.z??0,g:0,h:0,f:0,parent:{...t.A,z:t.A.z??0,g:0,h:0,f:0,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this,n=t.z===e.z?[t,e]:[t,{...this.boundsCenter,z:this.A.z},{...this.boundsCenter,z:e.z},e];this.solvedPath={connectionName:this.connectionName,route:n,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:this.A.z===this.B.z?[]:[this.boundsCenter]}}get viaPenaltyDistance(){return this.cellStep+this.straightLineDistance*this.VIA_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e,n){if(e??=this.obstacleMargin,n&&t.parent){const n=this.getViasInNodePath(t.parent);for(const s of n)if(k(t,s)<this.viaDiameter/2+e)return!0}for(const s of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,s.connectionName);if(!o){const o=Jn(s);for(const s of o)if((n||s.z===t.z)&&X(t,s.A,s.B)<this.traceThickness+e)return!0}for(const n of s.vias)if(k(t,n)<this.viaDiameter/2+this.traceThickness/2+e)return!0}return!1}isNodeTooCloseToEdge(t,e){const n=e?this.viaDiameter/2+this.obstacleMargin/2:this.obstacleMargin/2,s=t.x<this.bounds.minX+n||t.x>this.bounds.maxX-n||t.y<this.bounds.minY+n||t.y>this.bounds.maxY-n;return!(s&&!e&&(k(t,this.B)<2*n||k(t,this.A)<2*n))&&s}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s)for(const s of Jn(n))if(s.z===t.z&&D(t,e,s.A,s.B))return!0}return!1}computeH(t){return k(t,this.B)+(t.z!==this.B.z?this.viaPenaltyDistance:0)}computeG(t){return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+k(t,t.parent)}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getNodeKey(t){return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}`}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;const c={...t,parent:t,x:Kn(t.x+r*this.cellStep,s,n),y:Kn(t.y+a*this.cellStep,i,o)},h=this.getNodeKey(c);this.exploredNodes.has(h)||(this.isNodeTooCloseToObstacle(c)?(this.debug_nodesTooCloseToObstacle.add(h),this.exploredNodes.add(h)):this.isNodeTooCloseToEdge(c,!1)?this.exploredNodes.add(h):this.doesPathToParentIntersectObstacle(c)?(this.debug_nodePathToParentIntersectsObstacle.add(h),this.exploredNodes.add(h)):(c.g=this.computeG(c),c.h=this.computeH(c),c.f=this.computeF(c.g,c.h),e.push(c)))}for(let n=0;n<this.layerCount;n++){if(n===t.z)continue;const s={...t,parent:t,z:n};this.exploredNodes.has(this.getNodeKey(s))||this.isNodeTooCloseToObstacle(s,this.viaDiameter/2+this.obstacleMargin/2,!0)||this.isNodeTooCloseToEdge(s,!0)||(s.g=this.computeG(s),s.h=this.computeH(s),s.f=this.computeF(s.g,s.h),e.push(s))}return e}getNodePath(t){const e=[];for(;t;)e.push(t),t=t.parent;return e}getViasInNodePath(t){const e=this.getNodePath(t),n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});return n}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});this.solvedPath={connectionName:this.connectionName,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:e.map(t=>({x:t.x,y:t.y,z:t.z})).concat([this.B]),vias:n}}computeProgress(t,e,n){n||(e+=this.viaPenaltyDistance);const s=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*s/(1-s)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e);const n=k(t,this.B);this.progress=this.computeProgress(t,n,t.z===this.B.z),n<=this.cellStep*Math.SQRT2&&t.z===this.B.z&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++){const o=n.route[s].z;t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:0===o?"rgba(255, 0, 0, 0.75)":"rgba(255, 128, 0, 0.25)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`})}}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e],[s,o,i]=n.split(",").map(Number);this.debug_nodesTooCloseToObstacle.has(n)||(this.debug_nodePathToParentIntersectsObstacle.has(n)||t.rects.push({center:{x:s+this.initialNodeGridOffset.x+i*this.cellStep/20,y:o+this.initialNodeGridOffset.y+i*this.cellStep/20},fill:0===i?`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`:`rgba(0,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:`Explored (z=${i})`}))}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x+e.z*this.cellStep/20,y:e.y+e.z*this.cellStep/20},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:`Next (z=${e.z})`})}for(const e of this.obstacleRoutes)for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:this.viaDiameter/2,fill:"rgba(255, 0, 0, 0.5)",label:"Via"});if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route"});for(const e of this.solvedPath.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"green",label:"Via"})}return t}};function Jn(t){const e=[];for(let n=0;n<t.route.length-1;n++)t.route[n].z===t.route[n+1].z&&e.push({z:t.route[n].z,A:t.route[n],B:t.route[n+1]});return e}function Kn(t,e,n){return Math.max(e,Math.min(t,n))}var Qn=class extends qn{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR=2;FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR=1;FUTURE_CONNECTION_PROXIMITY_VD=10;MISALIGNED_DIST_PENALTY_FACTOR=5;VIA_PENALTY_FACTOR_2=1;FLIP_TRACE_ALIGNMENT_DIRECTION=!1;constructor(t){super(t);for(const e in t.hyperParameters)this[e]=t.hyperParameters[e];const e=this.boundsSize.width/this.viaDiameter,n=Math.max(1,this.numRoutes);this.VIA_PENALTY_FACTOR=e/n*.3*this.VIA_PENALTY_FACTOR_2}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o)+(t.z!==o.z?this.viaPenaltyDistance:0);s<e&&(e=s,n=o)}return n}diminishCloseToGoal(t){const e=k(t,this.B);return 1-Math.exp(-e/this.straightLineDistance*5)}getFutureConnectionPenalty(t,e){let n=0;const s=this.getClosestFutureConnectionPoint(t),o=k(t,this.B);if(s){const i=k(t,s);if(o<=i)return 0;const r=i/(this.viaDiameter*this.FUTURE_CONNECTION_PROXIMITY_VD);n=(e?this.straightLineDistance*this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:this.straightLineDistance*this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR)*Math.exp(5*-r)}return n}computeH(t){const e=k(t,this.B)**1.6;this.straightLineDistance;return e+(t.z!==this.B.z?this.viaPenaltyDistance:0)+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}computeG(t){const e=Math.abs(t.x-t.parent.x),n=Math.abs(t.y-t.parent.y),s=Math.sqrt(e**2+n**2),o=t.z%2==0,i=this.FLIP_TRACE_ALIGNMENT_DIRECTION?o?e:n:o?n:e;return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+s+i*this.MISALIGNED_DIST_PENALTY_FACTOR+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}},ts=class extends Ln{getSolverName(){return"IntraNodeRouteSolver"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;viaDiameter;traceWidth;activeSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??.3,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,x:n,y:o,z:i}of e.portPoints)s.set(t,[...s.get(t)??[],{x:n,y:o,z:i??0}]);this.unsolvedConnections=Array.from(s.entries().map(([t,e])=>({connectionName:t,points:e}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Vn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Vn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Gn(this.nodeWithPortPoints)}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o&&e.z===n.z)return;if(s&&o&&e.z!==n.z){const s={x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},o=[{x:e.x,y:e.y,z:e.z},{...s,z:e.z},{...s,z:n.z},{x:n.x,y:n.y,z:n.z}].filter((t,e,n)=>0===e||Math.abs(t.x-n[e-1].x)>1e-6||Math.abs(t.y-n[e-1].y)>1e-6||t.z!==n[e-1].z);return void this.solvedRoutes.push({connectionName:t.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:o,vias:[s]})}}const{connectionName:e,points:n}=t;this.activeSubSolver=new Qn({connectionName:e,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ne(this.nodeWithPortPoints),A:{x:n[0].x,y:n[0].y,z:n[0].z},B:{x:n[n.length-1].x,y:n[n.length-1].y,z:n[n.length-1].z},obstacleRoutes:this.connMap?this.solvedRoutes.filter(t=>!this.connMap.areIdsConnected(t.connectionName,e)):this.solvedRoutes,futureConnections:this.unsolvedConnections,layerCount:this.nodeWithPortPoints.portPoints.reduce((t,e)=>Math.max(t,(e.z??0)+1),2),hyperParameters:this.hyperParameters,connMap:this.connMap,viaDiameter:this.viaDiameter,traceThickness:this.traceWidth})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,`layer: ${e.z}`].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let o=0;o<n.route.length-1;o++){const i=n.route[o],r=n.route[o+1];t.lines.push({points:[i,r],strokeColor:0===i.z?Nn(s,.2):Nn(s,.8),layer:`route-layer-${i.z}`,step:e,strokeWidth:n.traceThickness})}for(const o of n.vias)t.circles.push({center:{x:o.x,y:o.y},radius:n.viaDiameter/2,fill:Nn(s,.5),layer:"via",step:e})}}const e=Ne(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},es=t=>Math.round(200*t)/200,ns=t=>"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t));Me();var ss=class extends ts{getSolverName(){return"CachedIntraNodeRouteSolver"}cacheProvider;cacheHit=!1;hasAttemptedToUseCache=!1;initialUnsolvedConnections;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider,this.initialUnsolvedConnections=ns(this.unsolvedConnections),(this.solved||this.failed)&&this.cacheProvider&&!this.cacheHit&&this.saveToCacheSync()}_step(){if(!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync())return;const t=this.solved,e=this.failed;super._step(),!this.cacheProvider||this.cacheHit||!this.solved&&!this.failed||t||e||this.saveToCacheSync()}computeCacheKeyAndTransform(){const t=this.nodeWithPortPoints.center,e=this.initialUnsolvedConnections.map(({connectionName:e,points:n})=>({connectionName:e,points:n.map(n=>({connectionName:e,x:es(n.x-t.x),y:es(n.y-t.y),z:n.z??0}))})),n=Object.fromEntries(Object.entries(this.hyperParameters??{}).filter(([,t])=>void 0!==t).sort(([t],[e])=>t.localeCompare(e))),s=this.connMap?this.initialUnsolvedConnections.map(({connectionName:t})=>({connectionName:t,connectedIds:[...new Set(this.connMap.getIdsConnectedToNet(t)??[])].sort()})):void 0,o={node:{width:es(this.nodeWithPortPoints.width),height:es(this.nodeWithPortPoints.height),center:{x:es(this.nodeWithPortPoints.center.x),y:es(this.nodeWithPortPoints.center.y)},availableZ:this.nodeWithPortPoints.availableZ?[...this.nodeWithPortPoints.availableZ].sort():void 0},normalizedConnections:e,normalizedHyperParameters:n,minDistBetweenEnteringPoints:es(this.minDistBetweenEnteringPoints),normalizedConnMap:s},i=`intranode-solver:${Wn(o)}`,r={};return this.cacheKey=i,this.cacheToSolveSpaceTransform=r,{cacheKey:i,cacheToSolveSpaceTransform:r}}applyCachedSolution(t){t.success?(this.solvedRoutes=ns(t.solvedRoutes),this.solved=!0,this.failed=!1):(this.solvedRoutes=[],this.failedSubSolvers=[],this.solved=!1,this.failed=!0,this.error=t.error??this.error),this.unsolvedConnections=[],this.activeSubSolver=null,this.cacheHit=!0,this.progress=1}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return!1;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return console.error("Error computing cache key:",t),!1}if(!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(null!=t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheProvider?.isSyncCache)return;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return void console.error("Error computing cache key during save:",t)}if(!this.cacheKey)return void console.error("Failed to compute cache key before saving.");const t=this.failed?{success:!1,error:this.error??void 0}:{success:!0,solvedRoutes:ns(this.solvedRoutes)};try{this.cacheProvider.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}},os=class extends Ln{getSolverName(){return"HyperParameterSupervisorSolver"}GREEDY_MULTIPLIER=1.2;MIN_SUBSTEPS=1;supervisedSolvers;winningSolver;getHyperParameterDefs(){throw new Error("Not implemented")}getCombinationDefs(){return null}getHyperParameterCombinations(t){t||(t=this.getHyperParameterDefs());const e=[];if(0===t.length)return[{}];const[n,...s]=t,o=this.getHyperParameterCombinations(s);return n.possibleValues.forEach(t=>{o.forEach(n=>{e.push({...n,...t})})}),e}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs()??[t.map(t=>t.name)];this.supervisedSolvers=[];for(const n of e){const e=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of e){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){throw new Error("Not implemented")}computeG(t){return t.iterations/t.MAX_ITERATIONS}computeH(t){return 1-(t.progress||0)}computeF(t,e){return t+e*this.GREEDY_MULTIPLIER}getSupervisedSolverWithBestFitness(){let t=1/0,e=null;for(const n of this.supervisedSolvers??[]){if(n.solver.solved)return n;if(n.solver.failed)continue;const s=n.f;s<t&&(t=s,e=n)}return e}getFailureMessage(){return`All solvers failed in hyper solver. Example failures: ${this.supervisedSolvers?.sort((t,e)=>e.f-t.f)?.slice(0,5).map(t=>t.solver.error).join(", ")}`}_step(){this.supervisedSolvers||this.initializeSolvers();const t=this.getSupervisedSolverWithBestFitness();if(!t)return this.failed=!0,void(this.error=this.getFailureMessage());for(let e=0;e<this.MIN_SUBSTEPS;e++)t.solver.step();this.activeSubSolver=t.solver,t.g=this.computeG(t.solver),t.h=this.computeH(t.solver),t.f=this.computeF(t.g,t.h),t.solver.solved&&(this.solved=!0,this.winningSolver=t.solver,this.onSolve?.(t))}onSolve(t){}visualize(){const t=this.getSupervisedSolverWithBestFitness();let e={lines:[],circles:[],points:[],rects:[]};return t&&(e=t.solver.visualize()),e}};function is({A:t,B:e,C:n,D:s,E:o,F:i,radius:r,margin:a,subdivisions:c=0}){const h=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),l=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o),r=s/i,a=o/i,c=-a,h=r;return{midpoint:{x:(t.x+e.x)/2,y:(t.y+e.y)/2},A_Opp:{x:t.x-r*n,y:t.y-a*n},A_Right:{x:t.x+c*n,y:t.y+h*n},A_Left:{x:t.x-c*n,y:t.y-h*n},B_Opp:{x:e.x+r*n,y:e.y+a*n},B_Right:{x:e.x+c*n,y:e.y+h*n},B_Left:{x:e.x-c*n,y:e.y-h*n}}},d=(t,e)=>{const n=k(t,e.start),s=k(t,e.end),o=k(e.start,e.end);return Math.abs(n+s-o)<1e-4},u=(t,e)=>{const{start:n,end:s}=t,{start:o,end:i}=e;if(d(n,e)||d(s,e)||d(o,t)||d(i,t))return!0;const r=s.x-n.x,a=s.y-n.y,c=i.x-o.x,h=i.y-o.y,l=r*h-a*c;if(Math.abs(l)<1e-4)return!1;const u=o.x-n.x,p=o.y-n.y,f=(u*h-p*c)/l,m=(u*a-p*r)/l;return f>0&&f<1&&m>0&&m<1},p=(t,e)=>{const n=[];for(let e=0;e<t.length-1;e++)n.push({start:t[e],end:t[e+1]});const s=[];for(let t=0;t<e.length-1;t++)s.push({start:e[t],end:e[t+1]});for(const t of n)for(const e of s)if(u(t,e))return!0;return!1},f=t=>{let e=0;for(let n=1;n<t.length;n++){const s=t[n].x-t[n-1].x,o=t[n].y-t[n-1].y;e+=Math.sqrt(s*s+o*o)}return e},m=(t,e)=>{const{start:n,end:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(0===r)return{...n,t:0};const a=Math.max(0,Math.min(1,((e.x-n.x)*o+(e.y-n.y)*i)/r));return{x:n.x+a*o,y:n.y+a*i,t:a}},g=(e,n,s)=>{const o=m(e,n);if(k(o,n)>=s)return o;const i=o.x-n.x,r=o.y-n.y,a=Math.sqrt(i*i+r*r);if(0===a){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Math.sqrt(i*i+r*r);return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}}return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}},y=l(t,e,r),x=l(t,e,r+a),v=(t,e,n,s,o)=>{const i=t.points;if(i.length<2)return i;const a=n+s,c=[i[0]];for(let t=0;t<i.length-1;t++){const n={start:i[t],end:i[t+1]};if(X(e,n.start,n.end)<a){const t=m(n,e),s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);let h=null;if(i>1e-6)h={x:e.x+a*s/i,y:e.y+a*o/i};else{const t=n.end.x-n.start.x,s=n.end.y-n.start.y,o=Math.sqrt(t*t+s*s);o>1e-6&&(h={x:e.x+a*t/o,y:e.y+a*s/o})}h&&k(n.start,h)>r/10&&c.push(h)}k(c[c.length-1],n.end)>r/10&&c.push(n.end)}if(c.length>1){const t=[c[0]];for(let e=1;e<c.length;e++)k(t[t.length-1],c[e])>r/10&&t.push(c[e]);return t}return c},b=(()=>{const t=[[n,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.B_Right,y.A_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,s],[n,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,s],[s,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.A_Right,y.B_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,n],[s,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,n]],e=[];for(let n=0;n<t.length;n++){const s=t[n],o={start:s[0],end:s[1]},i={start:s[s.length-2],end:s[s.length-1]},r={start:s[3],end:s[4]};u(o,i)||u(o,r)||u(i,r)||e.push({index:n+1,path:s,length:f(s)})}if(0===e.length)return{index:0,path:[]};const o=e.sort((t,e)=>t.length-e.length)[0],i=[...o.path],r=i[0],a=k(r,i[2]),c=k(r,i[3]),l=a<c?2:3;(a<k(r,i[1])||c<k(r,i[1]))&&i.splice(1,l-1);const d=i[i.length-1],p=k(d,i[i.length-3]),m=k(d,i[i.length-4]),g=p<m?i.length-3:i.length-4;return(p<k(d,i[i.length-2])||m<k(d,i[i.length-2]))&&i.splice(g+1,i.length-g-2),{index:o.index,path:i,startsAt:i[0]===n?"C":"D",goesTo:i[i.length-1]===n?"C":"D"}})(),P=c>0?((n,s)=>{if(n.length<2)return n;const o=[n[0]];for(let i=0;i<n.length-1;i++){const a={start:n[i],end:n[i+1]},c={x:(a.start.x+a.end.x)/2,y:(a.start.y+a.end.y)/2},h=k(c,t),l=k(c,e);if((h<=r||l<=r)&&Math.abs(h-l)>1e-4){const n=m(a,t),i=m(a,e),c=k(n,t),h=k(i,e)<r,l=c<r?g(a,t,r):null,d=h?g(a,e,r):null;let u=[];if(k(a.start,a.end)>r/2&&s>0)for(let n=1;n<=s;n++){const o=n/(s+1),i={x:a.start.x+o*(a.end.x-a.start.x),y:a.start.y+o*(a.end.y-a.start.y),t:o,isSpecial:!1},c=k(i,t),h=k(i,e);c<r||h<r||(l&&Math.abs(i.t-l.t)<.1||d&&Math.abs(i.t-d.t)<.1||u.push(i))}if(l&&u.push(l),d&&u.push(d),u.sort((t,e)=>t.t-e.t),u.length>1){const t=[u[0]];for(let e=1;e<u.length;e++){const n=t[t.length-1],s=u[e];k(n,s)>r/10&&t.push(s)}u=t}u.forEach(t=>o.push(t))}o.push(n[i+1])}if(o.length>1){const t=[o[0]];for(let e=1;e<o.length;e++){const n=t[t.length-1],s=o[e];k(n,s)>r/10&&t.push(s)}return t}return o})(b.path,c):b.path;let S=(()=>{if(0===b.path.length)return null;const n=(()=>{const n=h(y.A_Right,y.B_Right),s=h(y.B_Left,y.A_Left);return[{startsAt:"E",goesTo:"B",points:[o,e]},{startsAt:"E",goesTo:"A",points:[o,t]},{startsAt:"F",goesTo:"B",points:[i,e]},{startsAt:"F",goesTo:"A",points:[i,t]},{startsAt:"E",goesTo:"B",points:[o,n,e]},{startsAt:"E",goesTo:"A",points:[o,n,t]},{startsAt:"F",goesTo:"B",points:[i,n,e]},{startsAt:"F",goesTo:"A",points:[i,n,t]},{startsAt:"E",goesTo:"B",points:[o,s,e]},{startsAt:"E",goesTo:"A",points:[o,s,t]},{startsAt:"F",goesTo:"B",points:[i,s,e]},{startsAt:"F",goesTo:"A",points:[i,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,n,e]},{startsAt:"F",goesTo:"B",points:[i,x.B_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,s,t]},{startsAt:"F",goesTo:"A",points:[i,x.A_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Left,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,x.B_Opp,x.B_Right,n,t]}].map((t,e)=>({...t,index:e}))})(),s=n.filter(t=>"E"===t.startsAt),r=n.filter(t=>"F"===t.startsAt),a=[],c=[];for(const t of s)if(!p(t.points,b.path)){a.push(t);break}for(const t of r)if(!p(t.points,b.path)){c.push(t);break}return 0===a.length||0===c.length?null:{line1:a[0],line2:c[0]}})();if(S){const n="A"===S.line1.goesTo?e:t,s="A"===S.line2.goesTo?e:t,o=v(S.line1,n,r,a),i=v(S.line2,s,r,a);S={line1:{...S.line1,points:o},line2:{...S.line2,points:i}}}return{jPair:S,optimalPath:{startsAt:b.startsAt,goesTo:b.goesTo,points:P}}}var rs=class extends Ln{getSolverName(){return"TwoCrossingRoutesHighDensitySolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;escapeLayer=1;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const[e,n]=this.routes;if(!(e.startPort.z===e.endPort.z))return this.failed=!0,void(this.error="Route A must start and end on the same layer");if(!(n.startPort.z===n.endPort.z))return this.failed=!0,void(this.error="Route B must start and end on the same layer");if(!(e.startPort.z===n.startPort.z))return this.failed=!0,void(this.error="Both routes must be on the same layer");0===e.startPort.z?this.escapeLayer=1:this.escapeLayer=0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({startPort:{...s[0],z:s[0].z??0},endPort:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}doRoutesCross(t,e){return D(t.startPort,t.endPort,e.startPort,e.endPort)}calculateViaPositions(t,e){const n=this.bounds.maxX-this.bounds.minX,s=this.bounds.maxY-this.bounds.minY,o=this.bounds.minX,i=this.bounds.minY,r={width:n-2*this.obstacleMargin-this.viaDiameter,height:s-2*this.obstacleMargin-this.viaDiameter,x:o+this.obstacleMargin+this.viaDiameter/2,y:i+this.obstacleMargin+this.viaDiameter/2},a=this.viaDiameter+this.obstacleMargin,c=e.startPort,h=e.endPort,l=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}],d=(t,e)=>k(t,e),u=[];l.forEach((t,e)=>{d(t,c)>=a&&d(t,h)>=a&&u.push({...t,type:"corner",index:e})});const p=[{p1:l[0],p2:l[1]},{p1:l[1],p2:l[2]},{p1:l[2],p2:l[3]},{p1:l[3],p2:l[0]}];if([c,h].forEach((t,e)=>{p.forEach((n,s)=>{((t,e)=>{const n=t.x,s=t.y,o=t.r,i=e.p1.x,r=e.p1.y,a=e.p2.x,c=e.p2.y;if(Math.abs(a-i)<.001){const t=i,e=o*o-(t-n)**2;if(e<0)return[];if(Math.abs(e)<.001){const e=s;return e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const a=s+Math.sqrt(e),h=s-Math.sqrt(e),l=[];return a>=Math.min(r,c)&&a<=Math.max(r,c)&&l.push({x:t,y:a}),h>=Math.min(r,c)&&h<=Math.max(r,c)&&l.push({x:t,y:h}),l}const h=(c-r)/(a-i),l=r-h*i,d=1+h*h,u=2*(h*l-h*s-n),p=u*u-4*d*(n*n+(l-s)*(l-s)-o*o);if(p<0)return[];if(Math.abs(p)<.001){const t=-u/(2*d),e=h*t+l;return t>=Math.min(i,a)&&t<=Math.max(i,a)&&e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const f=(-u+Math.sqrt(p))/(2*d),m=(-u-Math.sqrt(p))/(2*d),g=h*f+l,y=h*m+l,x=[];return f>=Math.min(i,a)&&f<=Math.max(i,a)&&g>=Math.min(r,c)&&g<=Math.max(r,c)&&x.push({x:f,y:g}),m>=Math.min(i,a)&&m<=Math.max(i,a)&&y>=Math.min(r,c)&&y<=Math.max(r,c)&&x.push({x:m,y:y}),x})({...t,r:a},n).forEach(t=>{d(t,0===e?h:c)>=a&&u.push({...t,type:"intersection",circle:e,edge:s})})})}),u.length<2){const t=.8*a;if(l.forEach((e,n)=>{d(e,c)>=t&&d(e,h)>=t&&!u.some(t=>t.x===e.x&&t.y===e.y)&&u.push({...e,type:"relaxed_corner",index:n})}),u.length<2){const t=[...l].sort((t,e)=>{const n=Math.min(d(t,c),d(t,h));return Math.min(d(e,c),d(e,h))-n});for(const e of t)if(!u.some(t=>t.x===e.x&&t.y===e.y)&&(u.push({...e,type:"forced_corner"}),u.length>=2))break}}if(u.length<2)return null;let f=0,m=[u[0],u[u.length>1?1:0]];for(let t=0;t<u.length;t++)for(let e=t+1;e<u.length;e++){const n=d(u[t],u[e]);n>f&&(f=n,m=[u[t],u[e]])}let g={x:m[0].x,y:m[0].y},y={x:m[1].x,y:m[1].y};const x=k(g,t.startPort);return k(y,t.startPort)<x&&([g,y]=[y,g]),{via1:g,via2:y}}trySolveAOverB(t,e,n=!1){const s=n?this.calculateViaPositions(t,e):this.calculateViaPositions(e,t);if(!s)return!1;this.debugViaPositions.push(s);const{via1:o,via2:i}=this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(s));this.debugViaPositions.push({via1:o,via2:i});const{jPair:r,optimalPath:a}=is({A:o,B:i,C:t.startPort,D:t.endPort,E:e.startPort,F:e.endPort,radius:this.viaDiameter/2+this.obstacleMargin+this.traceThickness/2*1.5,margin:2*this.obstacleMargin+this.traceThickness/2*1.5,subdivisions:1});if(!r)return!1;const c={connectionName:t.connectionName,route:a.points.map(e=>({x:e.x,y:e.y,z:t.startPort.z??0})),traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};r.line2.points.reverse();const h={connectionName:e.connectionName,route:[...r.line1.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0})),{...r.line1.points[r.line1.points.length-1],z:this.escapeLayer},{...r.line2.points[0],z:this.escapeLayer},...r.line2.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0}))],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[o,i]};return this.solvedRoutes.push(c,h),!0}pushViasFromEndpoints(t){const e={...t.via1},n={...t.via2},s=[this.routes[0].startPort,this.routes[0].endPort,this.routes[1].startPort,this.routes[1].endPort],o=this.getMinDistanceBetweenViaCenters(),i=this.viaDiameter/2+2*this.traceThickness+2*this.obstacleMargin;for(let t=0;t<10;t++){let r=!1,a=!1;const c=.9**t;for(const t of s){const s=k(e,t);if(s<i){const n=(i-s)*c,o=e.x-t.x,a=e.y-t.y,h=Math.sqrt(o*o+a*a);h>1e-6&&(e.x+=o/h*n,e.y+=a/h*n,r=!0)}const o=k(n,t);if(o<i){const e=(i-o)*c,s=n.x-t.x,r=n.y-t.y,h=Math.sqrt(s*s+r*r);h>1e-6&&(n.x+=s/h*e,n.y+=r/h*e,a=!0)}}const h=k(e,n);if(h<o){const t=(o-h)/2,s=n.x-e.x,i=n.y-e.y,c=Math.sqrt(s*s+i*i);c>1e-6?(e.x-=s/c*t,e.y-=i/c*t,n.x+=s/c*t,n.y+=i/c*t,r=!0,a=!0):(e.x-=t,n.x+=t,r=!0,a=!0)}if(!r&&!a)break}const r=k(e,n);if(r<o){const t=(o-r)/2,s=n.x-e.x,i=n.y-e.y,a=Math.sqrt(s*s+i*i);a>1e-6?(e.x-=s/a*t,e.y-=i/a*t,n.x+=s/a*t,n.y+=i/a*t):(e.x-=t,n.x+=t)}return{via1:e,via2:n}}getMinDistanceBetweenViaCenters(){return this.viaDiameter+this.traceThickness+2*this.obstacleMargin}moveViasAsCloseAsPossible(t){const{via1:e,via2:n}=t,s=this.getMinDistanceBetweenViaCenters(),o=k(e,n);if(o<=s)return t;const i=n.x-e.x,r=n.y-e.y,a=Math.sqrt(i*i+r*r),c=i/a,h=r/a,l=(e.x,n.x,e.y,n.y,(o-s)/2);return{via1:{x:e.x+c*l,y:e.y+h*l},via2:{x:n.x-c*l,y:n.y-h*l}}}handleRoutesDontCross(){const[t,e]=this.routes,n={connectionName:t.connectionName,route:[{x:t.startPort.x,y:t.startPort.y,z:t.startPort.z??0},{x:t.endPort.x,y:t.endPort.y,z:t.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]},s={connectionName:e.connectionName,route:[{x:e.startPort.x,y:e.startPort.y,z:e.startPort.z??0},{x:e.endPort.x,y:e.endPort.y,z:e.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};this.solvedRoutes.push(n,s),this.solved=!0}_step(){if(2!==this.routes.length)return void(this.failed=!0);const[t,e]=this.routes;this.doRoutesCross(t,e)?this.trySolveAOverB(t,e)||this.trySolveAOverB(e,t)||this.trySolveAOverB(t,e,!0)||this.trySolveAOverB(e,t,!0)?this.solved=!0:(this.failed=!0,this.error="All crossover strategies failed"):this.handleRoutesDontCross()}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)"});for(const[e,n]of[["Route A",this.routes[0]],["Route B",this.routes[1]]])t.points.push({x:n.startPort.x,y:n.startPort.y,label:`${e}\n${n.connectionName} start`,color:"orange"}),t.points.push({x:n.endPort.x,y:n.endPort.y,label:`${e}\n${n.connectionName} end`,color:"orange"}),t.lines.push({points:[n.startPort,n.endPort],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e}\n${n.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via1:n,via2:s}=this.debugViaPositions[e],o=["rgba(255, 165, 0, 0.3)","rgba(128, 0, 128, 0.3)"],i=o[e%o.length];t.circles.push({center:n,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via A (attempt ${e+1})`}),t.circles.push({center:s,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via B (attempt ${e+1})`});const r=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 1 Safety Margin (attempt ${e+1})`}),t.circles.push({center:s,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 2 Safety Margin (attempt ${e+1})`}),t.lines.push({points:[this.routes[e%2].startPort,n,s,this.routes[e%2].endPort],strokeColor:`${i.substring(0,i.lastIndexOf(","))}, 0.3)`,strokeDash:[5,5],label:`Potential Route (attempt ${e+1})`})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:1===o.z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`}),o._label&&t.points.push({x:o.x,y:o.y,label:o._label})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Solved Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},as=({value:t,min:e,max:n})=>t>=e&&t<=n,cs=({value:t,target:e,epsilon:n})=>Math.abs(t-e)<=n,hs=({point:t,bounds:e,epsilon:n=1e-6})=>{if(![t.x,t.y,e.minX,e.maxX,e.minY,e.maxY].every(t=>(({value:t})=>Number.isFinite(t))({value:t})))return"outside";const s=function(t,e){return t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY?0:k(t,{x:L(t.x,e.minX,e.maxX),y:L(t.y,e.minY,e.maxY)})}(t,e);if(s>n)return"outside";const o=cs({value:t.x,target:e.minX,epsilon:n}),i=cs({value:t.x,target:e.maxX,epsilon:n}),r=cs({value:t.y,target:e.minY,epsilon:n}),a=cs({value:t.y,target:e.maxY,epsilon:n}),c=o||i,h=r||a;if(c&&h)return"on-boundary";const l=as({value:t.y,min:e.minY,max:e.maxY}),d=as({value:t.x,min:e.minX,max:e.maxX});return c&&l||h&&d?"on-boundary":"inside"};function ls(t,e,n,s,o){const i={x:(t.x+e.x+n.x)/3,y:(t.y+e.y+n.y)/3},r=(t,e)=>Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),a=i=>{const a=r(i,t),c=r(i,e),h=r(i,n),l=i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY;return a>=s&&c>=s&&h>=s&&l};if(a(i))return i;const c=(t,e,n)=>{const s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);return i<1e-10?{x:e.x+n,y:e.y}:{x:e.x+s/i*n,y:e.y+o/i*n}},h=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(i>2*n-1e-10||i<1e-10)return[];const a=i*i/(2*i),c=Math.sqrt(Math.max(0,n*n-a*a)),h=t.x+s*a/i,l=t.y+o*a/i,d={x:h+c*o/i,y:l-c*s/i},u={x:h-c*o/i,y:l+c*s/i},p=[],f=1e-6;return Math.abs(r(d,t)-n)<f&&Math.abs(r(d,e)-n)<f&&p.push(d),Math.abs(r(u,t)-n)<f&&Math.abs(r(u,e)-n)<f&&p.push(u),p},l=[c(i,t,s),c(i,e,s),c(i,n,s),...h(t,e,s),...h(e,n,s),...h(n,t,s)],d=l.filter(a);if(d.length>0){const t=d.filter(t=>!(t=>{const e=1e-6;return Math.abs(t.x-o.minX)<e||Math.abs(t.x-o.maxX)<e||Math.abs(t.y-o.minY)<e||Math.abs(t.y-o.maxY)<e})(t));if(t.length>0)return t.sort((t,e)=>r(t,i)-r(e,i)),t[0]}let u=null,p=1/0;for(let t=o.minX+1;t<o.maxX;t+=5)for(let e=o.minY+1;e<o.maxY;e+=5){const n={x:t,y:e};if(a(n)){const t=r(n,i);t<p&&(p=t,u=n)}}if(null!==u)return u;const f=[];for(let t=0;t<=100;t++){const e=t/100;f.push({x:o.minX+e*(o.maxX-o.minX),y:o.minY}),f.push({x:o.maxX,y:o.minY+e*(o.maxY-o.minY)}),f.push({x:o.maxX-e*(o.maxX-o.minX),y:o.maxY}),f.push({x:o.minX,y:o.maxY-e*(o.maxY-o.minY)})}const m=f.filter(a);if(m.length>0)return m.sort((t,e)=>r(t,i)-r(e,i)),m[0];let g=1/0,y={x:o.minX,y:o.minY};for(const i of[...l,...f])if(i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY){const o=Math.max(0,s-r(i,t))+Math.max(0,s-r(i,e))+Math.max(0,s-r(i,n));o<g&&(g=o,y=i)}return y}function ds(t,e,n){const s=us(e,t,n.center,n.radius),o=us(t,e,n.center,n.radius),i=ps(s,e),r=ps(t,o),a=1e-6;let c;if(i>a&&r>a){c={x:(s.x+o.x)/2,y:(s.y+o.y)/2};const i=ps(s,c),r=ps(o,c);if(Math.abs(i-r)>.5*Math.min(i,r)){const n=ps(t,s),i=ps(e,o),r=n+i;if(r>a){const t=i/r,e=n/r;c={x:s.x*t+o.x*e,y:s.y*t+o.y*e}}}const h=ps(c,n.center);if(h<1.05*n.radius){const t={x:(c.x-n.center.x)/h,y:(c.y-n.center.y)/h};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}}else{const s={x:(t.x+e.x)/2,y:(t.y+e.y)/2},o=ps(s,n.center);if(o<1.1*n.radius){const t={x:(s.x-n.center.x)/o,y:(s.y-n.center.y)/o};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}else c=s}return{B:s,D:o,E:c}}function us(t,e,n,s){const o=[n.x-t.x,n.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);if(i<=s){if(i<1e-8){const o=[e.x-t.x,e.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);return i<1e-8?{x:n.x+s,y:n.y}:{x:n.x+o[0]/i*s,y:n.y+o[1]/i*s}}const r=[o[0]/i,o[1]/i];return{x:n.x-r[0]*s,y:n.y-r[1]*s}}const r=[e.x-t.x,e.y-t.y],a=Math.sqrt(i*i-s*s),c=[o[0]/i,o[1]/i],h=[-c[1],c[0]],l=[c[1],-c[0]],d=r[0]*h[0]+r[1]*h[1]>r[0]*l[0]+r[1]*l[1]?h:l,u=s/i,p=a/i,f=[c[0]*p+d[0]*u,c[1]*p+d[1]*u];return{x:t.x+a*f[0],y:t.y+a*f[1]}}function ps(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var fs=1e-9;function ms(t,e,n,s="cw"){const o=gs(t,n),i=gs(e,n);return Math.abs(i-o)<fs?{left:0,top:0,right:0,bottom:0}:function(t,e,n,s){const o=n.maxX-n.minX,i=n.maxY-n.minY;if(o<fs&&i<fs)return{left:0,top:0,right:0,bottom:0};const r=2*(o+i);if(r<fs)return{left:0,top:0,right:0,bottom:0};const a=o/r*(2*Math.PI),c=(o+i)/r*(2*Math.PI),h=(o+o+i)/r*(2*Math.PI),l=2*Math.PI,d=[{name:"top",start:0,end:a,length:o},{name:"right",start:a,end:c,length:i},{name:"bottom",start:c,end:h,length:o},{name:"left",start:h,end:l,length:i}],u={left:0,top:0,right:0,bottom:0},p=(t,e,n,s,o)=>{const i=e>2*Math.PI-fs?2*Math.PI:e;if(i<=t+fs)return 0;if(o){const e=Math.max(t,n),o=Math.min(i,2*Math.PI),r=Math.max(0,o-e),a=Math.max(t,0),c=Math.min(i,s);return r+Math.max(0,c-a)}{const e=Math.max(t,n),o=Math.min(i,s);return Math.max(0,o-e)}};for(const n of d){const o=n.end-n.start;if(o<fs||n.length<fs)continue;let i=0;if("cw"===s){const s=t>e+fs;i=p(n.start,n.end,t,e,s)}else{const s=e>t+fs;i=p(n.start,n.end,e,t,s)}if(i>fs){const t=i/o;u[n.name]+=Math.max(0,Number.isFinite(t)?t:0)}}for(const t in u)u[t]=Math.max(0,Math.min(1,u[t]));return u}(o,i,n,s)}function gs(t,e){const n=e.maxX-e.minX,s=e.maxY-e.minY;if(n<fs&&s<fs)return 0;const o=2*(n+s);if(o<fs)return 0;let i=0;if(Math.abs(t.y-e.maxY)<fs&&t.x>=e.minX-fs&&t.x<=e.maxX+fs)i=Math.max(0,Math.min(n,t.x-e.minX));else if(Math.abs(t.x-e.maxX)<fs&&t.y>=e.minY-fs&&t.y<=e.maxY+fs)i=n+Math.max(0,Math.min(s,e.maxY-t.y));else if(Math.abs(t.y-e.minY)<fs&&t.x>=e.minX-fs&&t.x<=e.maxX+fs)i=n+s+Math.max(0,Math.min(n,e.maxX-t.x));else{if(!(Math.abs(t.x-e.minX)<fs&&t.y>=e.minY-fs&&t.y<=e.maxY+fs))throw new Error(`Point (${t.x}, ${t.y}) does not lie on the boundary defined by ${JSON.stringify(e)}`);i=n+s+n+Math.max(0,Math.min(s,t.y-e.minY))}return i=Math.max(0,Math.min(o,i)),o>fs?i/o*(2*Math.PI):0}function ys(t,e,n,s){return function({angleA:t,angleB:e,angleC:n}){const s=Math.cos(t),o=Math.sin(t),i=Math.cos(e),r=Math.sin(e),a=Math.cos(n);return(i-s)*(Math.sin(n)-o)-(r-o)*(a-s)<0?"ccw":"cw"}({angleA:gs(t,s),angleB:gs(e,s),angleC:gs(n,s)})}var xs=class extends Ln{getSolverName(){return"SingleTransitionCrossingRouteSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const e=this.routes.flatMap(t=>[t.A,t.B]).map(t=>this.getPortPointBoundsPosition(t));if(e.includes("outside"))return this.failed=!0,void(this.error="Invalid route input: SingleTransitionCrossingRouteSolver received port point(s) outside node bounds");if(e.includes("inside"))return void(this.failed=!0);const[n,s]=this.routes,o=n.A.z!==n.B.z,i=s.A.z!==s.B.z;return o&&i||!o&&!i?(this.failed=!0,void(this.error="Exactly one route must have a layer transition")):void 0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0],z:s[0].z??0},B:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}getPortPointBoundsPosition(t,e=1e-6){return hs({point:t,bounds:this.bounds,epsilon:e})}doRoutesCross(t,e){return D(t.A,t.B,e.A,e.B)}calculateViaPosition(t,e){const n=e.A.z,s=t.A.z!==n?t.A:t.B,o=2*this.obstacleMargin+this.viaDiameter/2+this.traceThickness,i=this.obstacleMargin+this.viaDiameter/2,r=e.A,a=s,c=e.B,h=ys(r,a,c,this.bounds),l=function(t,e,n,s,o){const i=ms(t,e,s,o),r=ms(e,n,s,o),a={left:Math.min(1,i.left+r.left),top:Math.min(1,i.top+r.top),right:Math.min(1,i.right+r.right),bottom:Math.min(1,i.bottom+r.bottom)};for(const t in a)Math.abs(a[t])<fs&&(a[t]=0);return a}(r,a,c,this.bounds,h),d={minX:this.bounds.minX+(l.left>.5?o:i),minY:this.bounds.minY+(l.bottom>.5?o:i),maxX:this.bounds.maxX-(l.right>.5?o:i),maxY:this.bounds.maxY-(l.top>.5?o:i)};return d.maxY<d.minY&&(d.minY=(d.minY+d.maxY)/2,d.maxY=d.minY),d.maxX<d.minX&&(d.minX=(d.minX+d.maxX)/2,d.maxX=d.minX),ls(r,a,c,o,d)}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z??0},{x:n.x,y:n.y,z:t.z??0},{x:n.x,y:n.y,z:e.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}createFlatRoute(t,e,n,s,o,i){s.z,t.z;const r=this.viaDiameter/2+this.traceThickness/2+this.obstacleMargin,a=((t,e,n,s)=>{const o=n.x-t.x,i=n.y-t.y;return((t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}))({x:t.x+o*e,y:t.y+i*e},{x:n.x-o*s,y:n.y-i*s})})(n,this.viaDiameter,s.z!==t.z?s:o,this.traceThickness),c={center:{x:n.x,y:n.y},radius:r},h=ds(t,a,c).E,l=ds(a,e,c).E,d=ds(t,h,c).E,u=ds(h,a,c).E,p=ds(a,l,c).E,f=ds(l,e,c).E,m=ds(u,p,c).E;return{connectionName:i,route:[{x:t.x,y:t.y,z:t.z??0},{x:d.x,y:d.y,z:t.z??0},{x:h.x,y:h.y,z:t.z??0},{x:u.x,y:u.y,z:t.z??0},{x:m.x,y:m.y,z:t.z??0},{x:p.x,y:p.y,z:t.z??0},{x:l.x,y:l.y,z:t.z??0},{x:f.x,y:f.y,z:t.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]}}trySolve(){const[t,e]=this.routes,n=t.A.z!==t.B.z,s=n?t:e,o=n?e:t,i=this.calculateViaPosition(s,o);if(!i)return!1;this.debugViaPositions.push({via:i});const r=this.createTransitionRoute(s.A,s.B,i,s.connectionName),a=this.createFlatRoute(o.A,o.B,i,s.A,s.B,o.connectionName);return this.solvedRoutes.push(r,a),!0}_step(){if(!this.doRoutesCross(this.routes[0],this.routes[1]))return this.failed=!0,void(this.error="Can only solve routes that have a single transition crossing");this.trySolve()?this.solved=!0:(this.failed=!0,this.error="Failed to find a valid via position and route path")}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"});for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via:n}=this.debugViaPositions[e];t.circles.push({center:n,radius:this.viaDiameter/2,fill:"rgba(255, 165, 0, 0.7)",stroke:"rgba(0, 0, 0, 0.5)",label:`Computed Via (attempt ${e+1})`});const s=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:s,stroke:"rgba(255, 165, 0, 0.7)",fill:"rgba(0, 0, 0, 0)",label:"Safety Margin"})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},vs=class extends Ln{getSolverName(){return"SingleTransitionIntraNodeSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),1!==this.routes.length)return this.failed=!0,void(this.error=`Expected 1 route, but got ${this.routes.length}`);const e=this.routes[0];if(void 0===e.A.z||void 0===e.B.z)return this.failed=!0,void(this.error="Route points should have predefined z values");if(e.A.z===e.B.z)return this.failed=!0,void(this.error="Only one route provided, but it has no transition");const n=this.viaDiameter/2+this.obstacleMargin,s={x:L((e.A.x+e.B.x)/2,this.bounds.minX+n,this.bounds.maxX-n),y:L((e.A.y+e.B.y)/2,this.bounds.minY+n,this.bounds.maxY-n)};this.solvedRoutes.push(this.createTransitionRoute(e.A,e.B,s,e.connectionName)),this.solved=!0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e).push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0]},B:{...s[1]},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z},{x:n.x,y:n.y,z:t.z},{x:n.x,y:n.y,z:e.z},{x:e.x,y:e.y,z:e.z}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}_step(){this.solved=!0}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"}),this.routes.length>0)for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s="rgba(0, 255, 0, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}},bs=(t,e)=>{const n={};return t.portPoints.forEach((e,s)=>{n[e.connectionName]=`hsl(${360*s/t.portPoints.length}, 100%, 50%)`}),n},Ps=class extends Ln{getSolverName(){return"ViaPossibilitiesSolver2"}bounds;maxViaCount;portPairMap;colorMap;nodeWidth;availableZ;hyperParameters;VIA_INTERSECTION_BUFFER_DISTANCE=.05;PLACEHOLDER_WALL_BUFFER_DISTANCE=.1;NEW_HEAD_WALL_BUFFER_DISTANCE=.05;viaDiameter;unprocessedConnections;completedPaths=new Map;placeholderPaths=new Map;currentHead;currentConnectionName;currentPath;currentViaCount;constructor({nodeWithPortPoints:t,colorMap:e,hyperParameters:n,viaDiameter:s}){super(),this.MAX_ITERATIONS=1e5,this.colorMap=e??bs(t),this.maxViaCount=5,this.bounds=Ne(t),this.nodeWidth=this.bounds.maxX-this.bounds.minX,this.portPairMap=(t=>{const e=new Map;return t.portPoints.forEach(t=>{e.has(t.connectionName)?e.get(t.connectionName).end=t:e.set(t.connectionName,{start:t,end:null,connectionName:t.connectionName})}),e})(t),this.stats.solutionsFound=0,this.availableZ=t.availableZ??[0,1],this.hyperParameters=n??{SHUFFLE_SEED:0},this.viaDiameter=s??.3,this.unprocessedConnections=Array.from(this.portPairMap.keys()).sort(),n?.SHUFFLE_SEED&&(this.unprocessedConnections=Vn(this.unprocessedConnections,n.SHUFFLE_SEED));for(const[t,{start:e,end:n}]of this.portPairMap.entries())if(e.z===n.z){const s=Math.abs(e.x-n.x)<1e-9,o=Math.abs(e.y-n.y)<1e-9;s||o?this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),this._padByPlaceholderWallBuffer(n),n]):this.placeholderPaths.set(t,[e,n])}else{const s=(e.x+n.x)/2,o=(e.y+n.y)/2,i=this._padByPlaceholderWallBuffer({x:s,y:o,z:e.z}),r=this._padByPlaceholderWallBuffer({x:s,y:o,z:n.z});this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),i,r,this._padByPlaceholderWallBuffer(n),n])}this.currentConnectionName=this.unprocessedConnections.pop();const o=this.portPairMap.get(this.currentConnectionName).start;this.currentHead=this._padByNewHeadWallBuffer(o),this.currentPath=[o,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}_padByNewHeadWallBuffer(t){return{x:L(t.x,this.bounds.minX+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.NEW_HEAD_WALL_BUFFER_DISTANCE),y:L(t.y,this.bounds.minY+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.NEW_HEAD_WALL_BUFFER_DISTANCE),z:t.z}}_padByPlaceholderWallBuffer(t){return{x:L(t.x,this.bounds.minX+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),y:L(t.y,this.bounds.minY+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),z:t.z}}_step(){if(this.solved)return;const t=this.portPairMap.get(this.currentConnectionName).end,e=[this.currentHead,t];let n=null,s=null;const o=t=>{for(const o of t.values())for(let t=0;t<o.length-1;t++){const i=[o[t],o[t+1]];if(i[0].x===i[1].x&&i[0].y===i[1].y)continue;if(i[0].z!==this.currentHead.z)continue;const r=$(e[0],e[1],i[0],i[1]);if(r){const t=k(this.currentHead,r);if(t<1e-6)continue;(!n||t<n.dist)&&(n={point:r,dist:t},s=i[0].z)}}};o(this.completedPaths),o(this.placeholderPaths);const i=this.currentHead.z!==t.z;if((n||i)&&(this.currentViaCount++,this.currentViaCount>=this.maxViaCount))return this.failed=!0,void(this.error=`Exceeded max via count of ${this.maxViaCount}`);if(n){let t;const e=n.dist;if(e<=this.VIA_INTERSECTION_BUFFER_DISTANCE+1e-6)t=B(this.currentHead,n.point);else{const s=n.point,o=s.x-this.currentHead.x,i=s.y-this.currentHead.y,r=(e-this.VIA_INTERSECTION_BUFFER_DISTANCE)/e;t={x:this.currentHead.x+o*r,y:this.currentHead.y+i*r}}const o=this.availableZ.find(t=>t!==s);if(void 0===o)return this.error="Could not determine next Z level for via placement!",void(this.failed=!0);const i={...t,z:this.currentHead.z},r={...t,z:o};this.currentPath.push(i,r),this.currentHead=r}else if(i){let e;const n=k(this.currentHead,t);if(n<this.VIA_INTERSECTION_BUFFER_DISTANCE)e=B(this.currentHead,t);else{const s=t.x-this.currentHead.x,o=t.y-this.currentHead.y,i=(n-this.VIA_INTERSECTION_BUFFER_DISTANCE)/n;e={x:this.currentHead.x+s*i,y:this.currentHead.y+o*i}}const s=t.z,o={...e,z:this.currentHead.z},i={...e,z:s};this.currentPath.push(o,i),this.currentHead=i}else if(this.currentPath.push(t),this.completedPaths.set(this.currentConnectionName,this.currentPath),0===this.unprocessedConnections.length)this.solved=!0,this.stats.solutionsFound=1;else{this.currentConnectionName=this.unprocessedConnections.pop();const{start:t}=this.portPairMap.get(this.currentConnectionName);this.currentHead=this._padByNewHeadWallBuffer(t),this.currentPath=[t,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Via Possibilities Solver State",coordinateSystem:"cartesian"},e=this.colorMap;t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray",strokeWidth:.01});for(const[e,{start:n,end:s}]of this.portPairMap.entries()){const o=this.colorMap[e]??"black";t.points.push({x:n.x,y:n.y,color:o,label:`Port: ${e} Start (z${n.z})`}),t.points.push({x:s.x,y:s.y,color:o,label:`Port: ${e} End (z${s.z})`})}const n=(n,s)=>{for(const[o,i]of n.entries()){const n=e[o]??"black";for(let e=0;e<i.length-1;e++){const r=i[e],a=i[e+1];r.x===a.x&&r.y===a.y&&r.z!==a.z?t.circles.push({center:{x:r.x,y:r.y},radius:this.viaDiameter/2,fill:Nn(n,.5),label:`${s}: ${o} Via (z${r.z}->z${a.z})`}):t.lines.push({points:[r,a],strokeColor:Nn(n,.5),strokeDash:0===r.z?void 0:[.1,.1],strokeWidth:.1,label:`${s}: ${o} (z${r.z})`})}}};if(n(this.placeholderPaths,"Placeholder"),n(this.completedPaths,"Completed"),this.currentPath&&this.currentPath.length>0){const n=e[this.currentConnectionName]??"orange";for(let e=0;e<this.currentPath.length-1;e++){const s=this.currentPath[e],o=this.currentPath[e+1];s.x===o.x&&s.y===o.y&&s.z!==o.z?t.circles.push({center:{x:s.x,y:s.y},radius:this.viaDiameter/2,fill:Nn(n,.5),label:`Current: ${this.currentConnectionName} Via (z${s.z}->z${o.z})`}):t.lines.push({points:[s,o],strokeColor:Nn(n,.5),strokeWidth:.15,strokeDash:"2,2",label:`Current: ${this.currentConnectionName} (z${s.z})`})}t.points.push({x:this.currentHead.x,y:this.currentHead.y,color:"green",label:`Current Head: ${this.currentConnectionName} (z${this.currentHead.z})`})}return t}},Ss=t=>Math.round(1e4*t),Ms=t=>{let e=0,n=[];const s=[];for(const e of t.portPoints){if(n.some(t=>t.connectionName===e.connectionName))continue;if(s.some(t=>t.connectionName===e.connectionName))continue;const o={connectionName:e.connectionName,z:e.z,points:[{x:Ss(e.x),y:Ss(e.y),z:e.z}]};for(const n of t.portPoints)e.connectionName===n.connectionName&&(e.x===n.x&&e.y===n.y||o.points.push({x:Ss(n.x),y:Ss(n.y),z:n.z}));o.points.some(t=>t.z!==o.z)?s.push(o):n.push(o)}n=n.filter(t=>t.points.length>1);for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];o.z===i.z&&D(o.points[0],o.points[1],i.points[0],i.points[1])&&e++}let o=0;for(let t=0;t<s.length;t++)for(let e=t+1;e<s.length;e++){const n=s[t],i=s[e];D(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:s.length,numTransitionPairCrossings:o}};var Ns=t=>{const{start:e,end:n,segmentsPerPolyline:s,viaPositions:o,viaCount:i,availableZ:r}=t,a=function(t,e){const n=new Array(t).fill(0);if(0===e)return n;if(e===t)return n.fill(1);if(e<=t/2){const s=Math.floor(t/e),o=Math.floor((t-(s*(e-1)+1))/2);for(let t=0;t<e;t++)n[o+t*s]=1}else{const s=t-e,o=Math.floor(t/s),i=Math.floor((t-(o*(s-1)+1))/2);n.fill(1);for(let t=0;t<s;t++)n[i+t*o]=0}return n}(s,i),c=a.map(()=>null);let h=0,l=e.z1;const d=r.indexOf(e.z1);for(let t=0;t<a.length;t++)if(1===a[t]){const e=r[(d+h+1)%r.length];c[t]={...o[h],z1:l,z2:e},l=e,h++}let u=e;for(let t=0;t<c.length;t++){if(c[t]){u=c[t];continue}let e=n,s=c.length;for(let n=t+1;n<c.length;n++)if(c[n]){e=c[n],s=n;break}const o=s-t,i=e.x-u.x,r=e.y-u.y;for(let e=1/(o+1),n=0;t+n!==s;e+=1/(o+1),n++)c[t+n]={x:u.x+i*e,y:u.y+r*e,z1:u.z2,z2:u.z2}}return c},Is=1e-9;function _s(t,e){return Math.abs(t-e)<Is}function Cs(t){return`${Math.round(t.x/Is)}:${Math.round(t.y/Is)}`}function Ts(t,e,n,s){return t*s-e*n}function Es(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Ts(o.x,o.y,i.x,i.y),a={x:n.x-t.x,y:n.y-t.y};if(_s(r,0))return null;const c=Ts(a.x,a.y,i.x,i.y)/r,h=Ts(a.x,a.y,o.x,o.y)/r;return c>=-1e-9&&c<=1+Is&&h>=-1e-9&&h<=1+Is?{x:t.x+c*o.x,y:t.y+c*o.y}:null}function ws(t,e,n){return _s(Math.hypot(t.x-e.x,t.y-e.y)+Math.hypot(t.x-n.x,t.y-n.y),Math.hypot(e.x-n.x,e.y-n.y))}function Rs(t,e){const n=[],s=new Map;for(const e of t){const t=[e.start,...e.mPoints,e.end];for(let o=0;o<t.length-1;o++){const i=t[o],r=t[o+1],a=i.z2;if(n.push({start:{x:i.x,y:i.y},end:{x:r.x,y:r.y},connectionName:e.connectionName,layer:a}),i.z1!==i.z2){const t=Cs(i);s.has(t)||s.set(t,{point:i,connectionName:e.connectionName})}}const o=t[t.length-1];if(o.z1!==o.z2){const t=Cs(o);s.has(t)||s.set(t,{point:o,connectionName:e.connectionName})}}const o=[{start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.maxY},end:{x:e.minX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.minX,y:e.maxY},end:{x:e.minX,y:e.minY},connectionName:null,layer:0}];n.push(...o);const i=new Map;let r=0;function a(t,e){const n=Cs(t);let o=i.get(n);if(!o){const e=s.has(n);o={id:r++,x:t.x,y:t.y,isVia:e,connectionNames:new Set,outgoingEdges:[]},i.set(n,o),e&&s.get(n)&&o.connectionNames.add(s.get(n).connectionName)}return e&&o.connectionNames.add(e),o}for(const t of n)a(t.start,t.connectionName),a(t.end,t.connectionName);const c=new Map;for(const t of n)c.set(t,[]);for(let t=0;t<n.length;t++)for(let e=t+1;e<n.length;e++){if(n[t].layer!==n[e].layer)continue;const s=Es(n[t].start,n[t].end,n[e].start,n[e].end);s&&(a(s),ws(s,n[t].start,n[t].end)&&c.get(n[t]).push(s),ws(s,n[e].start,n[e].end)&&c.get(n[e]).push(s))}const h=[];let l=0;for(const t of n){const e=[t.start,...c.get(t),t.end];e.sort((e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y;return Math.abs(s)>Math.abs(o)?(e.x-t.start.x)/s-(n.x-t.start.x)/s:Math.abs(o)<Is?0:(e.y-t.start.y)/o-(n.y-t.start.y)/o});const n=[];if(e.length>0){n.push(e[0]);for(let t=1;t<e.length;t++)_s(e[t].x,e[t-1].x)&&_s(e[t].y,e[t-1].y)||n.push(e[t])}for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1],i=a(s,t.connectionName),r=a(o,t.connectionName);if(i===r)continue;const c={id:l++,origin:i,twin:null,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1},d={id:l++,origin:r,twin:c,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1};c.twin=d,h.push(c,d),i.outgoingEdges.push(c),r.outgoingEdges.push(d)}}for(const t of i.values()){t.outgoingEdges.sort((e,n)=>{const s=e.twin.origin,o=n.twin.origin;return Math.atan2(s.y-t.y,s.x-t.x)-Math.atan2(o.y-t.y,o.x-t.x)});const e=t.outgoingEdges.length;for(let n=0;n<e;n++){const s=t.outgoingEdges[n],o=t.outgoingEdges[(n-1+e)%e];s.twin&&(s.twin.next=o)}}const d=[];let u=0,p=null,f=-1/0;for(const t of h){if(t.visited)continue;const e={id:u++,outerComponent:t,innerComponents:[],isOuterFace:!1};d.push(e);let n=t;const s=[],o=[],i=new Set;let r=0;do{if(!n||n.visited){console.warn("Face traversal encountered visited edge or null, breaking loop.",e.id),s.length=0;break}n.visited=!0,n.face=e,s.push(n),o.push(n.origin),null!==n.connectionName&&i.add(n.connectionName);const t=n.origin,a=n.twin.origin;r+=t.x*a.y-a.x*t.y,n=n.next}while(n!==t&&null!==n);if(n===t){if(r=.5*Math.abs(r),r>f&&(f=r,p&&(p.isOuterFace=!1),p=e,e.isOuterFace=!0),!e.isOuterFace&&s.length>0){if([...i].filter(t=>null!==t).length>1){let t=!1;for(const e of o)if(e.isVia){t=!0;break}if(!t)return!0}}}else console.warn(`Face ${e.id} did not close properly.`),d.pop(),u--}return!1}var Os=t=>{if(0===t.length)return[[]];const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=[...t.slice(0,n),...t.slice(n+1)],i=Os(o);for(const t of i)e.push([s,...t])}return e},As=1e-9;function zs(t,e,n=1e-9){return Math.abs(t-e)<n}function Ls(t,e,n,s){return t*s-e*n}function Ds(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Ls(o.x,o.y,i.x,i.y);if(zs(r,0))return null;const a={x:n.x-t.x,y:n.y-t.y},c=Ls(a.x,a.y,i.x,i.y)/r,h=Ls(a.x,a.y,o.x,o.y)/r;return c<-1e-9||c>1+As||h<-1e-9||h>1+As?null:{x:t.x+c*o.x,y:t.y+c*o.y}}function Fs(t){let e=0;for(let n=0,s=t.length;n<s;++n){const o=(n+1)%s;e+=t[n].x*t[o].y-t[o].x*t[n].y}return.5*e}function Ys(t){let e=0,n=0,s=0;for(let o=0,i=t.length;o<i;++o){const r=(o+1)%i,a=t[o].x*t[r].y-t[r].x*t[o].y;e+=a,n+=(t[o].x+t[r].x)*a,s+=(t[o].y+t[r].y)*a}return e*=.5,zs(e,0)?null:(n/=6*e,s/=6*e,{x:n,y:s})}var Xs=class{x;y;out;connectionNames;constructor(t,e){this.x=t,this.y=e,this.out=[],this.connectionNames=new Set}},ks=class{orig;dest;twin;next;visited;constructor(t,e){this.orig=t,this.dest=e,this.twin=null,this.next=null,this.visited=!1}};function $s(t,e){const n=[...e,...[{start:{x:t.minX,y:t.minY},end:{x:t.maxX,y:t.minY}},{start:{x:t.maxX,y:t.minY},end:{x:t.maxX,y:t.maxY}},{start:{x:t.maxX,y:t.maxY},end:{x:t.minX,y:t.maxY}},{start:{x:t.minX,y:t.maxY},end:{x:t.minX,y:t.minY}}]],s=n.map(()=>[]);for(let t=0;t<n.length;++t){const e=n[t];s[t].push(e.start,e.end)}for(let t=0;t<n.length;++t)for(let e=t+1;e<n.length;++e){const o=Ds(n[t].start,n[t].end,n[e].start,n[e].end);o&&(s[t].push(o),s[e].push(o))}const o=new Map,i=[];function r(t){const e=function(t,e=1e-9){return`${Math.round(t.x/e)}:${Math.round(t.y/e)}`}(t);if(!o.has(e)){const n=i.length;return o.set(e,n),i.push(new Xs(t.x,t.y)),n}return o.get(e)}const a=[];for(let t=0;t<n.length;++t){const e=n[t],o=s[t].slice();o.sort((t,n)=>{const s=e.end.x-e.start.x,o=e.end.y-e.start.y;return(zs(Math.abs(s),0)?(t.y-e.start.y)/o:(t.x-e.start.x)/s)-(zs(Math.abs(s),0)?(n.y-e.start.y)/o:(n.x-e.start.x)/s)});for(let t=0;t<o.length-1;++t){const n=o[t],s=o[t+1],c=r(n),h=r(s);c!==h&&(a.push([c,h]),e.connectionName&&(i[c].connectionNames.add(e.connectionName),i[h].connectionNames.add(e.connectionName)))}}const c=[];for(const[t,e]of a){const n=new ks(t,e),s=new ks(e,t);n.twin=c.length+1,s.twin=c.length;const o=c.length;c.push(n,s),i[t].out.push(o),i[e].out.push(o+1)}for(let t=0;t<i.length;++t){const e=i[t];e.out.sort((t,n)=>{const s=c[t],o=c[n],r=i[s.dest],a=i[o.dest];return Math.atan2(r.y-e.y,r.x-e.x)-Math.atan2(a.y-e.y,a.x-e.x)});const n=e.out.length;for(let t=0;t<n;++t){const s=e.out[t],o=e.out[(t-1+n)%n],i=c[s];null!==i.twin&&(c[i.twin].next=o)}}const h=[],l=[];for(let t=0;t<c.length;++t){if(c[t].visited)continue;let e=t;const n=[],s=[];do{if(null===e)break;const t=c[e];t.visited=!0,n.push(i[t.orig]),s.push(e),e=t.next}while(null!==e&&e!==t&&!c[e].visited);if(n.length<3)continue;if(Fs(n)>As){const t=Ys(n);t&&(h.push(t),l.push({vertices:n.map(t=>({x:t.x,y:t.y,connectionNames:t.connectionNames.size>0?t.connectionNames:void 0})),centroid:t}))}}return{centroids:h,faces:l,allVertices:i}}function Bs(t,e){if(t>e)throw new Error("oneCount cannot be greater than length");if(t<0||e<0)throw new Error("oneCount and length must be non-negative");const n=[];return function t(s,o,i){i!==e?(s[i]=0,t(s,o,i+1),o>0&&(s[i]=1,t(s,o-1,i+1))):0===o&&n.push([...s])}(Array(e).fill(0),t,0),n}var js=class extends Ln{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver"}nodeWithPortPoints;colorMap;hyperParameters;connMap;candidates;bounds;solvedRoutes=[];unsolvedConnections=[];SEGMENTS_PER_POLYLINE;cellSize;MAX_CANDIDATES=5e4;viaDiameter=.3;obstacleMargin=.1;traceWidth=.15;availableZ=[];uniqueConnections=0;BOUNDARY_PADDING;lastCandidate=null;maxViaCount;minViaCount;phase="setup";progress=0;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??bs(t.nodeWithPortPoints),this.hyperParameters=t.hyperParameters??{},this.SEGMENTS_PER_POLYLINE=t.hyperParameters?.SEGMENTS_PER_POLYLINE??3,this.BOUNDARY_PADDING=t.hyperParameters?.BOUNDARY_PADDING??.05,this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??this.viaDiameter,this.cellSize=this.nodeWithPortPoints.width/1024,this.candidates=[],this.availableZ=this.nodeWithPortPoints.availableZ??[0,1],this.bounds={minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2};const e=this.nodeWithPortPoints.width*this.nodeWithPortPoints.height,n=(this.viaDiameter+2*this.obstacleMargin+this.traceWidth/2)**2,s=new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size;this.uniqueConnections=s;const{numSameLayerCrossings:o,numEntryExitLayerChanges:i}=Ms(this.nodeWithPortPoints);if(this.minViaCount=2*o+i,this.maxViaCount=Math.min(Math.floor(e/n),Math.ceil(1.5*s)),this.minViaCount>this.SEGMENTS_PER_POLYLINE*(s/2))return this.failed=!0,void(this.error=`Not possible to solve problem with given SEGMENTS_PER_POLYLINE (${this.SEGMENTS_PER_POLYLINE}), atleast ${this.minViaCount} vias are required`);this.maxViaCount>this.SEGMENTS_PER_POLYLINE&&(this.maxViaCount=this.SEGMENTS_PER_POLYLINE),this.maxViaCount<this.minViaCount&&(this.maxViaCount=this.minViaCount)}computeMinGapBtwPolyLines(t){const e=[],n=[],s=[];for(let e=0;e<t.length;e++){const o=t[e],i=[o.start,...o.mPoints,o.end],r=new Map(this.availableZ.map(t=>[t,[]]));for(let t=0;t<i.length-1;t++){const e=[i[t],i[t+1]],n=e[0].z2;r.has(n)||r.set(n,[]),r.get(n).push(e)}n.push(r),s.push(i.filter(t=>t.z1!==t.z2))}for(let o=0;o<t.length;o++){const i=n[o],r=s[o];for(let a=o+1;a<t.length;a++){if(this.connMap?.areIdsConnected(t[o].connectionName,t[a].connectionName))continue;const c=n[a],h=s[a];let l=1;for(const t of this.availableZ){const e=i.get(t)??[],n=c.get(t)??[];for(const t of e)for(const e of n)l=Math.min(l,J(t[0],t[1],e[0],e[1])-this.traceWidth);for(const t of r)for(const e of n)l=Math.min(l,X(t,e[0],e[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of h)for(const n of e)l=Math.min(l,X(t,n[0],n[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of r)for(const e of h)l=Math.min(l,k(t,e)-this.viaDiameter)}e.push(l)}}return e}insertCandidate(t){let e=0,n=this.candidates.length-1;for(;e<=n;){const s=Math.floor((e+n)/2);this.candidates[s].f<t.f?e=s+1:n=s-1}this.candidates.splice(e,0,t)}setupInitialPolyLines(){const t=new Map;this.nodeWithPortPoints.portPoints.forEach(e=>{t.has(e.connectionName)?t.get(e.connectionName).end={...e,z1:e.z??0,z2:e.z??0}:t.set(e.connectionName,{start:{...e,z1:e.z??0,z2:e.z??0},end:null})});for(const[e,n]of t.entries())null===n.end&&t.delete(e);if(0===t.size)return this.failed=!0,void(this.error="No port pairs found, can't solve");const e=Array.from(t.entries()),n=((t,e,n,s)=>{const o=[];for(const[,n]of t){const t=n.start.z1!==n.end.z1,s=[];for(let n=0;n<=e;n++){const e=n%2!=0;t&&e?s.push(n):t||e||s.push(n)}o.push(s)}if(0===o.length)return[[]];let i=(t=>{if(!t||0===t.length)return[[]];let e=[[]];for(const n of t){const t=[];for(const s of e)for(const e of n)t.push([...s,e]);e=t}return e})(o).filter(t=>{for(let e=0;e<t.length;e++)if(t.reduce((t,e)=>t+e,0)<s)return!1;return!0});return i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(s.start.z1!==s.start.z2&&0===e[n])return!1}return!0}),i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(t[n][1].start.z1===t[n][1].start.z2)for(let o=n+1;o<t.length;o++){if(t[o][1].start.z1!==t[o][1].start.z2)continue;const[,i]=t[o];if(s.start.z1===s.end.z1&&i.start.z1===i.end.z1&&s.start.z1===i.start.z1&&D(s.start,s.end,i.start,i.end)&&e[n]+e[o]<2)return!1}}return!0}),i=i.filter(t=>!(t.reduce((t,e)=>t+e,0)>n)),i})(e,this.SEGMENTS_PER_POLYLINE,this.maxViaCount,this.minViaCount),s=(t=>{const{bounds:e,portPairsEntries:n,viaCountVariants:s}=t,{centroids:o}=$s(e,n.map(([t,e])=>e)),i=[];for(const t of s){const n=t.reduce((t,e)=>t+e,0);let s=o;if(o.length<n){s=[];const t=Math.ceil(Math.sqrt(n)),o=t;for(let n=0;n<t;n++)for(let i=0;i<o;i++)s.push({x:e.minX+(i+1)/(o+1)*(e.maxX-e.minX),y:e.minY+(n+1)/(t+1)*(e.maxY-e.minY)})}const r=Bs(n,s.length);for(const e of r){const n=[];for(let t=0;t<e.length;t++)1===e[t]&&n.push(s[t]);i.push({viaPositions:n,viaCountVariant:t})}}return i})({portPairsEntries:e,viaCountVariants:n,bounds:this.bounds}),o=[];for(const{viaCountVariant:t,viaPositions:e}of s){const n=Os(e);for(const e of n)o.push({viaCountVariant:t,viaPositions:e})}for(const{viaPositions:t,viaCountVariant:n}of o){const s=[];let o=0;for(let i=0;i<e.length;i++){const[r,a]=e[i],c=n[i],h=t.slice(o,o+c),l=Ns({start:a.start,end:a.end,segmentsPerPolyline:this.SEGMENTS_PER_POLYLINE,viaPositions:h,viaCount:c,availableZ:this.availableZ});o+=c,s.push({connectionName:r,start:a.start,end:a.end,mPoints:l})}if(Rs(s,this.bounds))continue;const i=this.computeMinGapBtwPolyLines(s),r=this.computeH({minGaps:i,forces:[]}),a={polyLines:s,g:0,h:r,f:r,viaCount:n.reduce((t,e)=>t+e,0),minGaps:i};if(this.checkIfSolved(a))return void(this.candidates=[a]);if(this.candidates.push(a),this.candidates.length>this.MAX_CANDIDATES)return}this.candidates.sort((t,e)=>t.f-e.f)}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){let e=0;for(const n of t.forces??[])for(const t of n)for(const n of t.values())e+=n.fx*n.fx+n.fy*n.fy;return e}getNeighbors(t){const{polyLines:e}=t,n=e.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(t,n)=>Array.from({length:e[n].mPoints.length},()=>new Map)),a=(t,n,s,o,i)=>{if(n>0&&n<e[t].mPoints.length+1){const e=n-1,a=r[t][e],c=a.get(s)||{fx:0,fy:0};a.set(s,{fx:c.fx+o,fy:c.fy+i})}};for(let t=0;t<n;t++)for(let o=t+1;o<n;o++){const n=e[t],r=e[o],c=[n.start,...n.mPoints,n.end],h=[r.start,...r.mPoints,r.end],l=[],d=[];for(let t=0;t<c.length-1;t++)l.push({p1:c[t],p2:c[t+1],layer:c[t].z2,p1Idx:t,p2Idx:t+1});c.forEach((t,e)=>{t.z1!==t.z2&&d.push({point:t,layers:[t.z1,t.z2],index:e})});const u=[],p=[];for(let t=0;t<h.length-1;t++)u.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&p.push({point:t,layers:[t.z1,t.z2],index:e})});for(const e of l)for(const n of u)if(e.layer===n.layer){if(J(e.p1,e.p2,n.p1,n.p2)<i)continue;const s={x:(e.p1.x+e.p2.x)/2,y:(e.p1.y+e.p2.y)/2},r={x:(n.p1.x+n.p2.x)/2,y:(n.p1.y+n.p2.y)/2},c=s.x-r.x,h=s.y-r.y,l=c*c+h*h;if(l>i){const s=Math.sqrt(l),r=(Math.exp(-6*s),`seg:${o}:${n.p1Idx}:${n.p2Idx}`),c=`seg:${t}:${e.p1Idx}:${e.p2Idx}`,h=(t,e,n,s,o,r,c)=>{const h=Q(t,n.p1,n.p2),l=t.x-h.x,d=t.y-h.y,u=l*l+d*d;if(u<=i)return;const p=Math.sqrt(u),f=.02*Math.exp(-6*p),m=l/p*f,g=d/p*f;a(s,e,r,m,g),a(o,n.p1Idx,c,-m/2,-g/2),a(o,n.p2Idx,c,-m/2,-g/2)};h(e.p1,e.p1Idx,n,t,o,r,c),h(e.p2,e.p2Idx,n,t,o,r,c),h(n.p1,n.p1Idx,e,o,t,c,r),h(n.p2,n.p2Idx,e,o,t,c,r)}}for(const e of d)for(const n of u)if(e.layers.includes(n.layer)){const r=Q(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${o}:${n.p1Idx}:${n.p2Idx}`;a(t,e.index,g,f,m);const y=`via:${t}:${e.index}`;a(o,n.p1Idx,y,-f/2,-m/2),a(o,n.p2Idx,y,-f/2,-m/2)}}for(const e of p)for(const n of l)if(e.layers.includes(n.layer)){const r=Q(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${t}:${n.p1Idx}:${n.p2Idx}`;a(o,e.index,g,f,m);const y=`via:${o}:${e.index}`;a(t,n.p1Idx,y,-f/2,-m/2),a(t,n.p2Idx,y,-f/2,-m/2)}}for(const e of d)for(const n of p){if(e.layers.filter(t=>n.layers.includes(t)).length>0){const r=e.point.x-n.point.x,c=e.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p,g=`via:${o}:${n.index}`,y=`via:${t}:${e.index}`;a(t,e.index,g,f,m),a(o,n.index,y,-f,-m)}}}}for(let t=0;t<n;t++){const n=e[t],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let e=0;e<r.length;e++)for(let n=e+1;n<r.length;n++){const o=r[e],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const e=Math.sqrt(d);let n=2,r=e;e<this.viaDiameter?(n*=4,r=Math.max(i,e)):r=Math.max(i,e-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/e*u,f=l/e*u,m=`via:${t}:${c.index}`,g=`via:${t}:${o.index}`;a(t,o.index,m,p,f),a(t,c.index,g,-p,-f)}}}const c=e.map(t=>({...t,mPoints:t.mPoints.map(t=>({...t}))}));let h=!1;for(let t=0;t<n;t++)for(let e=0;e<c[t].mPoints.length;e++){const n=c[t].mPoints[e],s=r[t][e],a={fx:0,fy:0};for(const t of s.values())a.fx+=t.fx,a.fy+=t.fy;const l=n.z1!==n.z2;let d=n.x+a.fx,u=n.y+a.fy;if(l){const t=this.viaDiameter/2;let e=0,s=0;const i=this.viaDiameter/2+this.BOUNDARY_PADDING,r=this.bounds.minX+i,c=this.bounds.maxX-i,h=this.bounds.minY+i,l=this.bounds.maxY-i,p=r+t-n.x,f=n.x-(c-t),m=h+t-n.y,g=n.y-(l-t);p>0?e=o*(Math.exp(p/(2*this.obstacleMargin))-1):f>0&&(e=-.008*(Math.exp(f/(2*this.obstacleMargin))-1)),m>0?s=o*(Math.exp(m/(2*this.obstacleMargin))-1):g>0&&(s=-.008*(Math.exp(g/(2*this.obstacleMargin))-1)),a.fx+=e,a.fy+=s,d=n.x+a.fx,u=n.y+a.fy}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;d=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,d)),u=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,u))}Math.abs(a.fx)<i&&Math.abs(a.fy)<i||(Math.abs(n.x-d)>i||Math.abs(n.y-u)>i)&&(n.x=d,n.y=u,h=!0)}if(!h)return[];const l=this.computeMinGapBtwPolyLines(c),d=this.computeG(c,t),u=this.computeH({minGaps:l,forces:r});return[{polyLines:c,g:d,h:u,f:Math.round(5*d)/5+u,minGaps:l,forces:r,viaCount:t.viaCount}]}checkIfSolved(t){const e=t.minGaps.every(t=>t>=this.obstacleMargin),n=t.polyLines.every(t=>t.mPoints.every(t=>{const e=(t.z1!==t.z2?this.viaDiameter/2:this.traceWidth/2)+this.BOUNDARY_PADDING;return((t,e,n=0)=>t.x>=e.minX+n&&t.x<=e.maxX-n&&t.y>=e.minY+n&&t.y<=e.maxY-n)(t,this.bounds,e)}));return e&&n}tryFinalAcceptance(){const t=this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP??void 0;if(void 0===t||null===this.lastCandidate||0===this.lastCandidate.minGaps.length)return;return Math.min(...this.lastCandidate.minGaps)>=t?(this.solved=!0,void this._setSolvedRoutes()):void 0}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return this.failed=!0,void(this.error="No candidates left")}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();if(!t)return void(this.failed=!0);const e=this.getNeighbors(t);for(const t of e)this.insertCandidate(t)}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"MultiHeadPolyLineIntraNodeSolver Visualization"};t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray"});const e=this.lastCandidate??this.candidates[0];if(e?.hasClosedSameLayerFace){const e=.1*(this.bounds.maxX-this.bounds.minX),n=.1*(this.bounds.maxY-this.bounds.minY);t.rects.push({center:{x:this.bounds.maxX+.6*e,y:this.bounds.maxY+.6*n},width:e,height:n,fill:"red",label:"HAS CLOSED FACE"})}for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:`${e.connectionName} (Port z=${e.z??0})`,color:this.colorMap[e.connectionName]??"blue"});return e&&e.polyLines.forEach((n,s)=>{const o=this.colorMap[n.connectionName]??"purple",i=[n.start,...n.mPoints,n.end];for(let e=0;e<i.length-1;e++){const s=i[e],r=i[e+1],a=s.z2,c=0===a,h=c?o:Nn(o,.5);t.lines.push({points:[s,r],strokeColor:h,strokeWidth:this.traceWidth,strokeDash:c?void 0:[.15,.15],label:`${n.connectionName} segment (z=${a})`})}i.forEach((r,a)=>{const c=r.z1!==r.z2,h=r.z1,l=a>0&&a<i.length-1;let d="",u="";if(l){const o=a-1,i=e.forces?.[s]?.[o];if(i&&i.size>0){const s={fx:0,fy:0};i.forEach((i,a)=>{if(s.fx+=i.fx,s.fy+=i.fy,Math.abs(i.fx)>1e-6||Math.abs(i.fy)>1e-6){const s=a.split(":"),c=s[0],h=parseInt(s[1],10),l=e.polyLines[h],d=this.colorMap[l.connectionName]??"gray",u=20,p={x:r.x+i.fx*u,y:r.y+i.fy*u};let f=l.connectionName;if("via"===c){f+=` Via ${parseInt(s[2],10)}`}else if("seg"===c){f+=` Seg ${parseInt(s[2],10)}-${parseInt(s[3],10)}`}t.lines.push({points:[r,p],strokeColor:d,strokeWidth:.02,strokeDash:"2,2",label:`Force by ${f} on ${n.connectionName} mPoint ${o}`})}}),(Math.abs(s.fx)>1e-6||Math.abs(s.fy)>1e-6)&&(u=`\nNet Force: (${s.fx.toFixed(3)}, ${s.fy.toFixed(3)})`)}}if(c)d=`Via (${n.connectionName} z=${r.z1} -> z=${r.z2})${u}`,t.circles.push({center:r,radius:this.viaDiameter/2,fill:Nn(o,.5),label:d});else if(l){const e=0===h?o:Nn(o,.5);d=`mPoint (${n.connectionName} z=${h})${u}`,t.circles.push({center:r,radius:this.cellSize/8,fill:e,label:d})}})}),t}_setSolvedRoutes(){if(!this.solved||!this.lastCandidate)return[];const t=[];for(const e of this.lastCandidate.polyLines){const n=[],s=[],o=[e.start,...e.mPoints,e.end];for(let t=0;t<o.length;t++){const e=o[t];n.push({x:e.x,y:e.y,z:e.z1}),e.z1!==e.z2&&(s.push({x:e.x,y:e.y}),n.push({x:e.x,y:e.y,z:e.z2}))}t.push({connectionName:e.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:n,vias:s})}this.solvedRoutes=t}},Ws=class extends js{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver2"}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){const{minGaps:e}=t;let n=0;for(const t of e)t<0&&(n+=this.obstacleMargin),t<this.obstacleMargin&&(n+=this.obstacleMargin-t);return.011*n}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return void(this.failed=!0)}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();let e=!1,n=0;const s=void 0===t.magForceApplied?1:10;for(let o=0;o<s;o++){const s=this.applyForcesToPolyLines(t.polyLines);if(n+=s.magForceApplied,e=s.lastStepMoved,!s.lastStepMoved)break}if(t.magForceApplied=n,t.minGaps=this.computeMinGapBtwPolyLines(t.polyLines),this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();t.g=this.computeG(t.polyLines,t),t.h=this.computeH(t),t.f=t.g+t.h,e&&this.insertCandidate(t)}applyForcesToPolyLines(t){let e=0;const n=t.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(e,n)=>Array.from({length:t[n].mPoints.length},()=>({fx:0,fy:0}))),a=(e,n,s,o)=>{if(n>0&&n<t[e].mPoints.length+1){const t=n-1;r[e][t].fx+=s,r[e][t].fy+=o}},c=(t,e,n,s,o)=>{const r=Q(t,n.p1,n.p2),c=t.x-r.x,h=t.y-r.y,l=c*c+h*h;if(l<=i)return;const d=Math.sqrt(l),u=.02*Math.exp(-6*d),p=c/d*u,f=h/d*u;a(s,e,p,f),a(o,n.p1Idx,-p/2,-f/2),a(o,n.p2Idx,-p/2,-f/2)};for(let e=0;e<n;e++)for(let o=e+1;o<n;o++){const n=t[e],r=t[o],h=[n.start,...n.mPoints,n.end],l=[r.start,...r.mPoints,r.end],d=[],u=[];for(let t=0;t<h.length-1;t++)d.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&u.push({point:t,layers:[t.z1,t.z2],index:e})});const p=[],f=[];for(let t=0;t<l.length-1;t++)p.push({p1:l[t],p2:l[t+1],layer:l[t].z2,p1Idx:t,p2Idx:t+1});l.forEach((t,e)=>{t.z1!==t.z2&&f.push({point:t,layers:[t.z1,t.z2],index:e})});for(const t of d)for(const n of p)if(t.layer===n.layer){J(t.p1,t.p2,n.p1,n.p2);c(t.p1,t.p1Idx,n,e,o),c(t.p2,t.p2Idx,n,e,o),c(n.p1,n.p1Idx,t,o,e),c(n.p2,n.p2Idx,t,o,e)}for(const t of u)for(const n of p)if(t.layers.includes(n.layer)){const r=Q(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(e,t.index,f,m),a(o,n.p1Idx,-f/2,-m/2),a(o,n.p2Idx,-f/2,-m/2)}}for(const t of f)for(const n of d)if(t.layers.includes(n.layer)){const r=Q(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(o,t.index,f,m),a(e,n.p1Idx,-f/2,-m/2),a(e,n.p2Idx,-f/2,-m/2)}}for(const t of u)for(const n of f){if(t.layers.filter(t=>n.layers.includes(t)).length>0){const r=t.point.x-n.point.x,c=t.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p;a(e,t.index,f,m),a(o,n.index,-f,-m)}}}}for(let e=0;e<n;e++){const n=t[e],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let t=0;t<r.length;t++)for(let n=t+1;n<r.length;n++){const o=r[t],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const t=Math.sqrt(d);let n=2,r=t;t<this.viaDiameter?(n*=4,r=Math.max(i,t)):r=Math.max(i,t-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/t*u,f=l/t*u;a(e,o.index,p,f),a(e,c.index,-p,-f)}}}let h=!1;for(let s=0;s<n;s++)for(let n=0;n<t[s].mPoints.length;n++){const a=t[s].mPoints[n],c=r[s][n],l=a.z1!==a.z2;let d=c.fx,u=c.fy,p=a.x+d,f=a.y+u;if(l){const t=this.viaDiameter/2;let e=0,n=0;const s=this.viaDiameter/2+this.BOUNDARY_PADDING,i=this.bounds.minX+s,r=this.bounds.maxX-s,c=this.bounds.minY+s,h=this.bounds.maxY-s,l=i+t-a.x,m=a.x-(r-t),g=c+t-a.y,y=a.y-(h-t);l>0?e=o*(Math.exp(l/(2*this.obstacleMargin))-1):m>0&&(e=-.008*(Math.exp(m/(2*this.obstacleMargin))-1)),g>0?n=o*(Math.exp(g/(2*this.obstacleMargin))-1):y>0&&(n=-.008*(Math.exp(y/(2*this.obstacleMargin))-1)),d+=e,u+=n,p=a.x+d,f=a.y+u}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;p=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,p)),f=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,f))}if(Math.abs(d)<i&&Math.abs(u)<i)continue;e+=Math.sqrt(d*d+u*u),(Math.abs(a.x-p)>i||Math.abs(a.y-f)>i)&&(a.x=p,a.y=f,h=!0)}return{lastStepMoved:h,magForceApplied:e}}},Hs=t=>t.flatMap(t=>`${t.connectionName}-${t.mPoints.map(t=>`${t.x.toFixed(2)},${t.y.toFixed(2)},${t.z1},${t.z2}`)}`).sort().join("|");var Us=class extends Ws{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver3"}constructor(t){super(t),this.MAX_ITERATIONS=1e3}createInitialCandidateFromSeed(t){const e=new Ps({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:{SHUFFLE_SEED:t},viaDiameter:this.viaDiameter});if(e.solve(),e.failed||!e.solved)return this.failed=!0,this.error=`ViaPossibilitiesSolver2 failed with: ${e.error}`,null;const n=[];let s=0;for(const[t,o]of e.completedPaths.entries()){if(o.length<2){console.warn(`Skipping connection "${t}" due to insufficient points (${o.length}) in ViaPossibilitiesSolver2 path.`);continue}const e=o[0],i=o[o.length-1],r=o.slice(1,-1),a=[];let c=0,h=e.z;for(let t=0;t<r.length;t++){const e=r[t],n=t+1<r.length?r[t+1]:i,s=h,o=t+1<r.length&&e.x===n.x&&e.y===n.y&&e.z!==n.z?n.z:e.z;a.push({x:e.x,y:e.y,z1:s,z2:o}),s!==o?(c++,t++,h=o):h=e.z}s+=c;const l=this.SEGMENTS_PER_POLYLINE;let d=a.length+1;for(;d<l;){let n=-1,s=-1,o=null,r=null;const c=[{...e,z1:e.z,z2:e.z,connectionName:t},...a,{...i,z1:i.z,z2:i.z,connectionName:t}];for(let t=0;t<c.length-1;t++){const e=c[t],i=c[t+1];if(e.x===i.x&&e.y===i.y)continue;const a=k(e,i);a>n&&(n=a,s=t,o=e,r=i)}if(-1===s||!o||!r){console.warn(`Could not find longest segment for ${t} while trying to reach ${l} segments.`);break}const h=(o.x+r.x)/2,u=(o.y+r.y)/2,p=o.z2,f={x:h,y:u,z1:p,z2:p};a.splice(s,0,f),d++}n.push({connectionName:t,start:{...e,z1:e.z,z2:e.z},end:{...i,z1:i.z,z2:i.z},mPoints:a})}if(0===n.length)return this.failed=!0,this.error="No valid polylines generated from ViaPossibilitiesSolver2.",console.error(this.error),null;const o=this.computeMinGapBtwPolyLines(n),i=this.computeH({minGaps:o,forces:[]}),r={polyLines:n,g:0,h:i,f:0+i,viaCount:s,minGaps:o};return r.g=this.computeG(n,r),r.f=r.g+r.h,r}setupInitialPolyLines(){this.candidates=[];const t=Math.min(2e3,function(t){if(!Number.isInteger(t)||t<0)throw new RangeError("n must be a non-negative integer");let e=1;for(let n=2;n<=t;n++)e*=n;return e}(this.uniqueConnections)),e=new Set;for(let n=0;n<t;n++){const t=this.createInitialCandidateFromSeed(n);if(!t)continue;const s=Hs(t.polyLines);e.has(s)||(e.add(s),this.candidates.push(t))}this.candidates.sort((t,e)=>t.f-e.f)}};import{HighDensitySolverA01 as Vs}from"@tscircuit/high-density-a01";var Gs=Object.create,Zs=Object.defineProperty,qs=Object.getOwnPropertyDescriptor,Js=Object.getOwnPropertyNames,Ks=Object.getPrototypeOf,Qs=Object.prototype.hasOwnProperty,to=(t,e)=>function(){return e||(0,t[Js(t)[0]])((e={exports:{}}).exports,e),e.exports},eo=to({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>=0?(i=r,o=r-1):s=r+1}return i}function s(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>0?(i=r,o=r-1):s=r+1}return i}function o(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<0?(i=r,s=r+1):o=r-1}return i}function i(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<=0?(i=r,s=r+1):o=r-1}return i}function r(t,e,n,s,o){for(;s<=o;){var i=s+o>>>1,r=t[i],a=void 0!==n?n(r,e):r-e;if(0===a)return i;a<=0?s=i+1:o=i-1}return-1}function a(t,e,n,s,o,i){return"function"==typeof n?i(t,e,n,void 0===s?0:0|s,void 0===o?t.length-1:0|o):i(t,e,void 0,void 0===n?0:0|n,void 0===s?t.length-1:0|s)}e.exports={ge:function(t,e,s,o,i){return a(t,e,s,o,i,n)},gt:function(t,e,n,o,i){return a(t,e,n,o,i,s)},lt:function(t,e,n,s,i){return a(t,e,n,s,i,o)},le:function(t,e,n,s,o){return a(t,e,n,s,o,i)},eq:function(t,e,n,s,o){return a(t,e,n,s,o,r)}}}}),no=to({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,s){var o=t*e,i=n*t,r=i-(i-t),a=t-r,c=n*e,h=c-(c-e),l=e-h,d=a*l-(o-r*h-a*h-r*l);if(s)return s[0]=d,s[1]=o,s;return[d,o]};var n=+(Math.pow(2,27)+1)}}),so=to({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),oo=to({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var s=t+e,o=s-t,i=e-o,r=t-(s-o);if(n)return n[0]=r+i,n[1]=s,n;return[r+i,s]}}}),io=to({"node_modules/robust-scale/robust-scale.js"(t,e){var n=no(),s=oo();e.exports=function(t,e){var o=t.length;if(1===o){var i=n(t[0],e);return i[0]?i:[i[1]]}var r=new Array(2*o),a=[.1,.1],c=[.1,.1],h=0;n(t[0],e,a),a[0]&&(r[h++]=a[0]);for(var l=1;l<o;++l){n(t[l],e,c);var d=a[1];s(d,c[0],a),a[0]&&(r[h++]=a[0]);var u=c[1],p=a[1],f=u+p,m=p-(f-u);a[1]=f,m&&(r[h++]=m)}a[1]&&(r[h++]=a[1]);0===h&&(r[h++]=0);return r.length=h,r}}}),ro=to({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],-e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=-e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=-e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=-e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),ao=to({"node_modules/robust-orientation/orientation.js"(t,e){var n=no(),s=so(),o=io(),i=ro();function r(t,e,n,s){return function(n,o,i){var r=t(t(e(o[1],i[0]),e(-i[1],o[0])),t(e(n[1],o[0]),e(-o[1],n[0]))),a=t(e(n[1],i[0]),e(-i[1],n[0])),c=s(r,a);return c[c.length-1]}}function a(t,e,n,s){return function(o,i,r,a){var c=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2])))),h=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2])))),l=s(c,h);return l[l.length-1]}}function c(t,e,n,s){return function(o,i,r,a,c){var h=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),i[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),-r[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),a[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),-c[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-i[3])))),t(t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),a[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),-c[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),o[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-i[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-a[3]))))),l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-r[3])),t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),a[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),o[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),-i[3])),t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-c[3])))),d=s(h,l);return d[d.length-1]}}function h(t){return(3===t?r:4===t?a:c)(s,n,o,i)}var l=h(3),d=h(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var s,o=(t[1]-n[1])*(e[0]-n[0]),i=(t[0]-n[0])*(e[1]-n[1]),r=o-i;if(o>0){if(i<=0)return r;s=o+i}else{if(!(o<0))return r;if(i>=0)return r;s=-(o+i)}var a=33306690738754716e-32*s;return r>=a||r<=-a?r:l(t,e,n)},function(t,e,n,s){var o=t[0]-s[0],i=e[0]-s[0],r=n[0]-s[0],a=t[1]-s[1],c=e[1]-s[1],h=n[1]-s[1],l=t[2]-s[2],u=e[2]-s[2],p=n[2]-s[2],f=i*h,m=r*c,g=r*a,y=o*h,x=o*c,v=i*a,b=l*(f-m)+u*(g-y)+p*(x-v),P=7771561172376103e-31*((Math.abs(f)+Math.abs(m))*Math.abs(l)+(Math.abs(g)+Math.abs(y))*Math.abs(u)+(Math.abs(x)+Math.abs(v))*Math.abs(p));return b>P||-b>P?b:d(t,e,n,s)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=h(t.length)),e.apply(void 0,t)}function f(t,e,n,s,o,i,r){return function(e,n,a,c,h){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,a);case 4:return i(e,n,a,c);case 5:return r(e,n,a,c,h)}for(var l=new Array(arguments.length),d=0;d<arguments.length;++d)l[d]=arguments[d];return t(l)}}!function(){for(;u.length<=5;)u.push(h(u.length));e.exports=f.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),co=to({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=eo(),s=ao()[3];function o(t,e,n,s,o){this.a=t,this.b=e,this.idx=n,this.lowerIds=s,this.upperIds=o}function i(t,e,n,s){this.a=t,this.b=e,this.type=n,this.idx=s}function r(t,e){var n=t.a[0]-e.a[0]||t.a[1]-e.a[1]||t.type-e.type;return n||(0!==t.type&&(n=s(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return s(t.a,t.b,e)}function c(t,e,o,i,r){for(var c=n.lt(e,i,a),h=n.gt(e,i,a),l=c;l<h;++l){for(var d=e[l],u=d.lowerIds,p=u.length;p>1&&s(o[u[p-2]],o[u[p-1]],i)>0;)t.push([u[p-1],u[p-2],r]),p-=1;u.length=p,u.push(r);var f=d.upperIds;for(p=f.length;p>1&&s(o[f[p-2]],o[f[p-1]],i)<0;)t.push([f[p-2],f[p-1],r]),p-=1;f.length=p,f.push(r)}}function h(t,e){var n;return(n=t.a[0]<e.a[0]?s(t.a,t.b,e.a):s(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?s(t.a,t.b,e.b):s(e.b,e.a,t.b))||t.idx-e.idx}function l(t,e,s){var i=n.le(t,s,h),r=t[i],a=r.upperIds,c=a[a.length-1];r.upperIds=[c],t.splice(i+1,0,new o(s.a,s.b,s.idx,[c],a))}function d(t,e,s){var o=s.a;s.a=s.b,s.b=o;var i=n.eq(t,s,h),r=t[i];t[i-1].upperIds=r.upperIds,t.splice(i,1)}e.exports=function(t,e){for(var n=t.length,s=e.length,a=[],h=0;h<n;++h)a.push(new i(t[h],null,0,h));for(h=0;h<s;++h){var u=e[h],p=t[u[0]],f=t[u[1]];p[0]<f[0]?a.push(new i(p,f,2,h),new i(f,p,1,h)):p[0]>f[0]&&a.push(new i(f,p,2,h),new i(p,f,1,h))}a.sort(r);for(var m=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),g=[new o([m,1],[m,0],-1,[],[],[],[])],y=[],x=(h=0,a.length);h<x;++h){var v=a[h],b=v.type;0===b?c(y,g,t,v.a,v.idx):2===b?l(g,t,v):d(g,t,v)}return y}}}),ho=to({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=eo();function s(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),o=0;o<t;++o)n[o]=[];return new s(n,e)};var o=s.prototype;function i(t,e,n){for(var s=1,o=t.length;s<o;s+=2)if(t[s-1]===e&&t[s]===n)return t[s-1]=t[o-2],t[s]=t[o-1],void(t.length=o-2)}o.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(s,o){return t[0]=Math.min(s,o),t[1]=Math.max(s,o),n.eq(this.edges,t,e)>=0}}(),o.removeTriangle=function(t,e,n){var s=this.stars;i(s[t],e,n),i(s[e],n,t),i(s[n],t,e)},o.addTriangle=function(t,e,n){var s=this.stars;s[t].push(e,n),s[e].push(n,t),s[n].push(t,e)},o.opposite=function(t,e){for(var n=this.stars[e],s=1,o=n.length;s<o;s+=2)if(n[s]===t)return n[s-1];return-1},o.flip=function(t,e){var n=this.opposite(t,e),s=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,s),this.addTriangle(t,s,n),this.addTriangle(e,n,s)},o.edges=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2)e.push([o[i],o[i+1]]);return e},o.cells=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2){var a=o[i],c=o[i+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),lo=to({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=no(),s=so(),o=ro(),i=io();function r(t){return(3===t?a:4===t?c:5===t?h:l)(s,o,n,i)}function a(t,e,n,s){return function(o,i,r){var a=n(o[0],o[0]),c=s(a,i[0]),h=s(a,r[0]),l=n(i[0],i[0]),d=s(l,o[0]),u=s(l,r[0]),p=n(r[0],r[0]),f=s(p,o[0]),m=s(p,i[0]),g=t(e(m,u),e(d,c)),y=e(f,h),x=e(g,y);return x[x.length-1]}}function c(t,e,n,s){return function(o,i,r,a){var c=t(n(o[0],o[0]),n(o[1],o[1])),h=s(c,i[0]),l=s(c,r[0]),d=s(c,a[0]),u=t(n(i[0],i[0]),n(i[1],i[1])),p=s(u,o[0]),f=s(u,r[0]),m=s(u,a[0]),g=t(n(r[0],r[0]),n(r[1],r[1])),y=s(g,o[0]),x=s(g,i[0]),v=s(g,a[0]),b=t(n(a[0],a[0]),n(a[1],a[1])),P=s(b,o[0]),S=s(b,i[0]),M=s(b,r[0]),N=t(t(s(e(M,v),i[1]),t(s(e(S,m),-r[1]),s(e(x,f),a[1]))),t(s(e(S,m),o[1]),t(s(e(P,d),-i[1]),s(e(p,h),a[1])))),I=t(t(s(e(M,v),o[1]),t(s(e(P,d),-r[1]),s(e(y,l),a[1]))),t(s(e(x,f),o[1]),t(s(e(y,l),-i[1]),s(e(p,h),r[1])))),_=e(N,I);return _[_.length-1]}}function h(t,e,n,s){return function(o,i,r,a,c){var h=t(n(o[0],o[0]),t(n(o[1],o[1]),n(o[2],o[2]))),l=s(h,i[0]),d=s(h,r[0]),u=s(h,a[0]),p=s(h,c[0]),f=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),m=s(f,o[0]),g=s(f,r[0]),y=s(f,a[0]),x=s(f,c[0]),v=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),b=s(v,o[0]),P=s(v,i[0]),S=s(v,a[0]),M=s(v,c[0]),N=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),I=s(N,o[0]),_=s(N,i[0]),C=s(N,r[0]),T=s(N,c[0]),E=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),w=s(E,o[0]),R=s(E,i[0]),O=s(E,r[0]),A=s(E,a[0]),z=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),i[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),-r[2]),s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),a[2]))),t(s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),-c[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-i[2])))),t(t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),a[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),-c[2]),s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),o[2]))),t(s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-i[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-a[2]))))),L=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-r[2])),t(s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),a[2]),s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-c[2]))),t(t(s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),o[2]),s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),-i[2])),t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-c[2])))),D=e(z,L);return D[D.length-1]}}function l(t,e,n,s){return function(o,i,r,a,c,h){var l=t(t(n(o[0],o[0]),n(o[1],o[1])),t(n(o[2],o[2]),n(o[3],o[3]))),d=s(l,i[0]),u=s(l,r[0]),p=s(l,a[0]),f=s(l,c[0]),m=s(l,h[0]),g=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),y=s(g,o[0]),x=s(g,r[0]),v=s(g,a[0]),b=s(g,c[0]),P=s(g,h[0]),S=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),M=s(S,o[0]),N=s(S,i[0]),I=s(S,a[0]),_=s(S,c[0]),C=s(S,h[0]),T=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),E=s(T,o[0]),w=s(T,i[0]),R=s(T,r[0]),O=s(T,c[0]),A=s(T,h[0]),z=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),L=s(z,o[0]),D=s(z,i[0]),F=s(z,r[0]),Y=s(z,a[0]),X=s(z,h[0]),k=t(t(n(h[0],h[0]),n(h[1],h[1])),t(n(h[2],h[2]),n(h[3],h[3]))),$=s(k,o[0]),B=s(k,i[0]),j=s(k,r[0]),W=s(k,a[0]),H=s(k,c[0]),U=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),i[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),a[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),o[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-i[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),r[3])),t(s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),h[3]))))),V=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),o[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(D,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(L,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),r[3]),s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),o[3]))),t(t(s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),-i[3]),s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(D,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(L,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),r[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(D,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(L,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(D,b),o[1]),t(s(e(L,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),c[3]))))),G=e(U,V);return G[G.length-1]}}var d=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=d[t.length];return e||(e=d[t.length]=r(t.length)),e.apply(void 0,t)}function p(t,e,n,s,o,i,r,a){return function(e,n,c,h,l,d){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,c);case 4:return i(e,n,c,h);case 5:return r(e,n,c,h,l);case 6:return a(e,n,c,h,l,d)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;d.length<=6;)d.push(r(d.length));e.exports=p.apply(void 0,[u].concat(d));for(var t=0;t<=6;++t)e.exports[t]=d[t]}()}}),uo=to({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=lo()[4];eo();function s(t,e,s,o,i,r){var a=e.opposite(o,i);if(!(a<0)){if(i<o){var c=o;o=i,i=c,c=r,r=a,a=c}e.isConstraint(o,i)||n(t[o],t[i],t[r],t[a])<0&&s.push(o,i)}}e.exports=function(t,e){for(var o=[],i=t.length,r=e.stars,a=0;a<i;++a)for(var c=r[a],h=1;h<c.length;h+=2){if(!((p=c[h])<a)&&!e.isConstraint(a,p)){for(var l=c[h-1],d=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){d=c[u];break}d<0||n(t[a],t[p],t[l],t[d])<0&&o.push(a,p)}}for(;o.length>0;){for(var p=o.pop(),f=(l=-1,d=-1,c=r[a=o.pop()],1);f<c.length;f+=2){var m=c[f-1],g=c[f];m===p?d=g:g===p&&(l=m)}l<0||d<0||(n(t[a],t[p],t[l],t[d])>=0||(e.flip(a,p),s(t,e,o,l,a,d),s(t,e,o,a,d,l),s(t,e,o,d,p,l),s(t,e,o,p,l,d)))}}}}),po=to({"node_modules/cdt2d/lib/filter.js"(t,e){var n=eo();function s(t,e,n,s,o,i,r){this.cells=t,this.neighbor=e,this.flags=s,this.constraint=n,this.active=o,this.next=i,this.boundary=r}function o(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var i=function(t,e){for(var n=t.cells(),i=n.length,r=0;r<i;++r){var a=(y=n[r])[0],c=y[1],h=y[2];c<h?c<a&&(y[0]=c,y[1]=h,y[2]=a):h<a&&(y[0]=h,y[1]=a,y[2]=c)}n.sort(o);var l=new Array(i);for(r=0;r<l.length;++r)l[r]=0;var d=[],u=[],p=new Array(3*i),f=new Array(3*i),m=null;e&&(m=[]);var g=new s(n,p,f,l,d,u,m);for(r=0;r<i;++r)for(var y=n[r],x=0;x<3;++x){a=y[x],c=y[(x+1)%3];var v=p[3*r+x]=g.locate(c,a,t.opposite(c,a)),b=f[3*r+x]=t.isConstraint(a,c);v<0&&(b?u.push(r):(d.push(r),l[r]=1),e&&m.push([c,a,-1]))}return g}(t,n);if(0===e)return n?i.cells.concat(i.boundary):i.cells;var r=1,a=i.active,c=i.next,h=i.flags,l=i.cells,d=i.constraint,u=i.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(h[p]!==-r){h[p]=r;l[p];for(var f=0;f<3;++f){var m=u[3*p+f];m>=0&&0===h[m]&&(d[3*p+f]?c.push(m):(a.push(m),h[m]=r))}}}var g=c;c=a,a=g,c.length=0,r=-r}var y=function(t,e,n){for(var s=0,o=0;o<t.length;++o)e[o]===n&&(t[s++]=t[o]);return t.length=s,t}(l,h,e);if(n)return y.concat(i.boundary);return y},s.prototype.locate=function(){var t=[0,0,0];return function(e,s,i){var r=e,a=s,c=i;return s<i?s<e&&(r=s,a=i,c=e):i<e&&(r=i,a=e,c=s),r<0?-1:(t[0]=r,t[1]=a,t[2]=c,n.eq(this.cells,t,o))}}()}}),fo=to({"node_modules/cdt2d/cdt2d.js"(t,e){var n=co(),s=ho(),o=uo(),i=po();function r(t){return[Math.min(t[0],t[1]),Math.max(t[0],t[1])]}function a(t,e){return t[0]-e[0]||t[1]-e[1]}function c(t,e,n){return e in t?t[e]:n}e.exports=function(t,e,h){Array.isArray(e)?(h=h||{},e=e||[]):(h=e||{},e=[]);var l=!!c(h,"delaunay",!0),d=!!c(h,"interior",!0),u=!!c(h,"exterior",!0),p=!!c(h,"infinity",!1);if(!d&&!u||0===t.length)return[];var f=n(t,e);if(l||d!==u||p){for(var m=s(t.length,function(t){return t.map(r).sort(a)}(e)),g=0;g<f.length;++g){var y=f[g];m.addTriangle(y[0],y[1],y[2])}return l&&o(t,m),u?d?p?i(m,0,p):m.cells():i(m,1,p):i(m,-1)}return f}}}),mo=class{heap=[];maxSize;constructor(t=[],e=1e4){if(this.maxSize=e,t.length>0){this.heap=[...t].sort((t,e)=>t.f-e.f).slice(0,this.maxSize);for(let t=Math.floor(this.heap.length/2)-1;t>=0;t--)this._siftDown(t)}}get size(){return this.heap.length}isEmpty(){return 0===this.heap.length}peek(){return this.isEmpty()?null:this.heap[0]??null}peekMany(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}dequeue(){if(this.isEmpty())return null;const t=this.heap[0],e=this.heap.pop();return 0===this.heap.length&&void 0!==e||void 0!==e&&(this.heap[0]=e,this._siftDown(0)),t}enqueue(t){this.heap.length>=this.maxSize||(this.heap.push(t),this._siftUp(this.heap.length-1))}_siftUp(t){let e=t;for(;e>0;){const t=this._parentIndex(e);if(this.heap[t].f<=this.heap[e].f)break;this._swap(e,t),e=t}}_siftDown(t){let e=t;const n=this.heap.length;for(;;){const t=this._leftChildIndex(e),s=this._rightChildIndex(e);let o=e;if(t<n&&this.heap[t].f<this.heap[o].f&&(o=t),s<n&&this.heap[s].f<this.heap[o].f&&(o=s),o===e)break;this._swap(e,o),e=o}}_swap(t,e){[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]]}_parentIndex(t){return Math.floor((t-1)/2)}_leftChildIndex(t){return 2*t+1}_rightChildIndex(t){return 2*t+2}},go=class extends N{constructor(t){super(),this.input=t,this.graph=(t=>{if(t.ports.length>0&&"region1"in t.ports[0]&&"object"==typeof t.ports[0].region1)return t;const e=new Map,n=new Map;for(const e of t.regions){const{assignments:t,...s}=e;n.set(e.regionId,{...s,ports:[],assignments:void 0})}for(const s of t.ports){const t=n.get(s.region1Id??s.region1?.regionId),o=n.get(s.region2Id??s.region2?.regionId),i={portId:s.portId,region1:t,region2:o,d:s.d};e.set(s.portId,i),t.ports.push(i),o.ports.push(i)}return{ports:Array.from(e.values()),regions:Array.from(n.values())}})(t.inputGraph);for(const t of this.graph.regions)t.assignments=[];this.connections=((t,e)=>{const n=[];for(const s of t)"startRegionId"in s?n.push({connectionId:s.connectionId,mutuallyConnectedNetworkId:s.connectionId,startRegion:e.regions.find(t=>t.regionId===s.startRegionId),endRegion:e.regions.find(t=>t.regionId===s.endRegionId)}):n.push(s);return n})(t.inputConnections,this.graph),void 0!==t.greedyMultiplier&&(this.greedyMultiplier=t.greedyMultiplier),void 0!==t.rippingEnabled&&(this.rippingEnabled=t.rippingEnabled),void 0!==t.ripCost&&(this.ripCost=t.ripCost),this.unprocessedConnections=[...this.connections],this.candidateQueue=new mo,this.beginNewConnection()}getSolverName(){return"HyperGraphSolver"}graph;connections;candidateQueue;unprocessedConnections;solvedRoutes=[];currentConnection=null;currentEndRegion=null;greedyMultiplier=1;rippingEnabled=!1;ripCost=0;lastCandidate=null;visitedPointsForCurrentConnection=new Map;getConstructorParams(){return{inputGraph:(e=this.graph,{ports:e.ports.map(t=>({portId:t.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:t.d})),regions:e.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.portId),d:t.d}))}),inputConnections:(t=this.connections,t.map(t=>({connectionId:t.connectionId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId}))),greedyMultiplier:this.greedyMultiplier,rippingEnabled:this.rippingEnabled,ripCost:this.ripCost};var t,e}computeH(t){return this.estimateCostToEnd(t.port)}estimateCostToEnd(t){return 0}getPortUsagePenalty(t){return 0}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){return 0}getRipsRequiredForPortUsage(t,e,n){return[]}isRipRequiredForPortUsage(t,e,n){return!1}isTransitionAllowed(t,e,n){return!0}computeG(t){return t.parent.g+this.computeIncreasedRegionCostIfPortsAreUsed(t.lastRegion,t.lastPort,t.port)+(t.ripRequired?this.ripCost:0)+this.getPortUsagePenalty(t.port)}selectCandidatesForEnteringRegion(t){return t}computeRoutesToRip(t){const e=this.computeCrossingRoutes(t),n=this.computePortOverlapRoutes(t);return new Set([...e,...n])}computePortOverlapRoutes(t){const e=new Set;for(const n of t.path)n.port.assignment&&n.port.assignment.connection.mutuallyConnectedNetworkId!==t.connection.mutuallyConnectedNetworkId&&e.add(n.port.assignment.solvedRoute);return e}computeCrossingRoutes(t){const e=new Set;for(const n of t.path){if(!n.lastPort||!n.lastRegion)continue;const t=this.getRipsRequiredForPortUsage(n.lastRegion,n.lastPort,n.port);for(const n of t)e.add(n.solvedRoute)}return e}getNextCandidates(t){const e=t.nextRegion,n=t.port,s={};for(const o of e.ports){if(o===t.port)continue;if(!this.isTransitionAllowed(e,n,o))continue;const i=o.assignment&&o.assignment.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId||this.isRipRequiredForPortUsage(e,n,o),r={port:o,hops:t.hops+1,parent:t,lastRegion:e,nextRegion:o.region1===e?o.region2:o.region1,lastPort:n,ripRequired:i};!this.rippingEnabled&&r.ripRequired||(s[r.nextRegion.regionId]??=[],s[r.nextRegion.regionId].push(r))}const o=[];for(const t in s){const e=s[t];o.push(...this.selectCandidatesForEnteringRegion(e))}for(const t of o)t.g=this.computeG(t),t.h=this.computeH(t),t.f=t.g+t.h*this.greedyMultiplier;return o}processSolvedRoute(t){const e={path:[],connection:this.currentConnection,requiredRip:!1};let n=t,s=!1;for(;n;)s||=!!n.ripRequired,e.path.unshift(n),n=n.parent;s&&(e.requiredRip=!0);const o=this.computeRoutesToRip(e);if(o.size>0){e.requiredRip=!0;for(const t of o)this.ripSolvedRoute(t)}for(const t of e.path){if(t.port.assignment={solvedRoute:e,connection:this.currentConnection},!t.lastPort)continue;const n={regionPort1:t.lastPort,regionPort2:t.port,region:t.lastRegion,connection:this.currentConnection,solvedRoute:e};t.lastRegion.assignments?.push(n)}this.solvedRoutes.push(e),this.routeSolvedHook(e)}routeSolvedHook(t){}routeStartedHook(t){}ripSolvedRoute(t){for(const e of t.path.map(t=>t.port))e.ripCount=(e.ripCount??0)+1,e.region1.assignments=e.region1.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.region2.assignments=e.region2.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.assignment=void 0;this.solvedRoutes=this.solvedRoutes.filter(e=>e!==t),this.unprocessedConnections.push(t.connection)}beginNewConnection(){this.currentConnection=this.unprocessedConnections.shift(),this.currentEndRegion=this.currentConnection.endRegion,this.candidateQueue=new mo,this.visitedPointsForCurrentConnection.clear(),this.routeStartedHook(this.currentConnection);for(const t of this.currentConnection.startRegion.ports)this.candidateQueue.enqueue({port:t,g:0,h:0,f:0,hops:0,ripRequired:!1,nextRegion:t.region1===this.currentConnection.startRegion?t.region2:t.region1})}_step(){let t=this.candidateQueue.dequeue();if(!t)return this.failed=!0,void(this.error="Ran out of candidates");let e=this.visitedPointsForCurrentConnection.get(t.port.portId);for(;t&&void 0!==e&&!(t.g<e)&&(t=this.candidateQueue.dequeue(),t);)e=this.visitedPointsForCurrentConnection.get(t.port.portId);if(!t)return this.failed=!0,void(this.error="Ran out of candidates");if(this.lastCandidate=t,this.visitedPointsForCurrentConnection.set(t.port.portId,t.g),t.nextRegion===this.currentEndRegion)return this.processSolvedRoute(t),0===this.unprocessedConnections.length?void(this.solved=!0):void this.beginNewConnection();const n=this.getNextCandidates(t);for(const t of n)this.candidateQueue.enqueue(t)}};function yo(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function xo(t){return void 0===t}function vo(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function bo(...t){const e=(t,e)=>({a:t.a*e.a+t.c*e.b,c:t.a*e.c+t.c*e.d,e:t.a*e.e+t.c*e.f+t.e,b:t.b*e.a+t.d*e.b,d:t.b*e.c+t.d*e.d,f:t.b*e.e+t.d*e.f+t.f});switch((t=Array.isArray(t[0])?t[0]:t).length){case 0:throw new Error("no matrices provided");case 1:return t[0];case 2:return e(t[0],t[1]);default:{const[n,s,...o]=t;return bo(e(n,s),...o)}}}var{cos:Po,sin:So,PI:Mo}=Math;var{tan:No}=Math,Io=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t){const{bounds:t}=i.d;e=Math.min(e,t.minX),n=Math.max(n,t.maxX),s=Math.min(s,t.minY),o=Math.max(o,t.maxY)}return{minX:e,maxX:n,minY:s,maxY:o}},_o=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Co=(t,e)=>{const n=t.regions.map(t=>{const{bounds:n,center:s,...o}=t.d,i=[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.minX,y:n.maxY},{x:n.maxX,y:n.maxY}].map(t=>yo(e,t)),r={minX:Math.min(...i.map(t=>t.x)),maxX:Math.max(...i.map(t=>t.x)),minY:Math.min(...i.map(t=>t.y)),maxY:Math.max(...i.map(t=>t.y))},a=yo(e,s);return{...t,ports:[],d:{...o,bounds:r,center:a}}}),s=new Map;for(let e=0;e<t.regions.length;e++)s.set(t.regions[e],n[e]);const o=t.ports.map(t=>{const n=yo(e,t.d),o=s.get(t.region1),i=s.get(t.region2),r={...t,region1:o,region2:i,d:n};return o.ports.push(r),i.ports.push(r),r}),i=t.jumperLocations?.map(t=>{const n=yo(e,t.center),o=t.padRegions.map(t=>s.get(t)),i=yo(e,{x:1,y:0}),r=yo(e,{x:0,y:0}),a=i.x-r.x,c=i.y-r.y;return{center:n,orientation:Math.abs(c)>Math.abs(a)?"horizontal"===t.orientation?"vertical":"horizontal":t.orientation,padRegions:o}});return{regions:n,ports:o,...i&&{jumperLocations:i}}};function To(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function Eo(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function wo(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=t.x-e.x,r=t.y-e.y,a=s*s+o*o,c=a>0?(h=(i*s+r*o)/a,l=0,d=1,Math.max(l,Math.min(d,h))):0;var h,l,d;return{u:c,d2:To(t,{x:e.x+c*s,y:e.y+c*o})}}function Ro(t){const e=t.d.polygon;if(!e||e.length<3)return null;const n=t.d.polygonPerimeterCache;if(n)return n;const s=function(t){const e=t.length,n=new Array(e),s=new Array(e+1);s[0]=0;for(let o=0;o<e;o++){const i=t[o],r=t[(o+1)%e],a=Math.hypot(r.x-i.x,r.y-i.y);n[o]=a,s[o+1]=s[o]+a}return{edgeLengths:n,cumulative:s,perimeter:s[e]}}(e);return t.d.polygonPerimeterCache=s,s}function Oo(t){const e=Ro(t);if(e)return e.perimeter;const{minX:n,maxX:s,minY:o,maxY:i}=t.d.bounds;return 2*(s-n)+2*(i-o)}function Ao(t,e){if(t.region1===e){if("number"==typeof t.region1T)return t.region1T;const n=zo(t.d,e);return t.region1T=n,n}if(t.region2===e){if("number"==typeof t.region2T)return t.region2T;const n=zo(t.d,e);return t.region2T=n,n}return zo(t.d,e)}function zo(t,e){const n=e.d.polygon;if(n&&n.length>=3){const s=Ro(e);if(s)return function(t,e,n,s=1e-6){let o=0,i=0,r=Number.POSITIVE_INFINITY;const a=s*s;for(let n=0;n<e.length;n++){const s=wo(t,e[n],e[(n+1)%e.length]);if(s.d2<=a){o=n,i=s.u,r=s.d2;break}s.d2<r&&(o=n,i=s.u,r=s.d2)}return n.cumulative[o]+i*n.edgeLengths[o]}(t,n,s)}const{minX:s,maxX:o,minY:i,maxY:r}=e.d.bounds;return Eo(t,s,o,i,r)}function Lo(t,e,n=1e-6){return Math.abs(t-e)<n}function Do(t,e){return(t%e+e)%e}function Fo(t,e,n,s){const o=Math.abs(Do(t-e,n));return o<s||n-o<s}function Yo(t,e,n,s,o){const i=Do(t,s),r=Do(e,s),a=Do(n,s);return!(Math.abs(r-a)<o)&&(r<a?r<i&&i<a:i>r||i<a)}function Xo(t,e,n){if("number"==typeof n&&n>0){let[s,o]=t,[i,r]=e;if(s=Do(s,n),o=Do(o,n),i=Do(i,n),r=Do(r,n),Fo(s,i,n,1e-6)||Fo(s,r,n,1e-6)||Fo(o,i,n,1e-6)||Fo(o,r,n,1e-6))return!1;return Yo(i,s,o,n,1e-12)!==Yo(r,s,o,n,1e-12)}const[s,o]=t[0]<t[1]?t:[t[1],t[0]],[i,r]=e[0]<e[1]?e:[e[1],e[0]];return!(Lo(s,i)||Lo(s,r)||Lo(o,i)||Lo(o,r))&&(s<i&&i<o&&o<r||i<s&&s<r&&r<o)}function ko(t,e){if(e.length<2)return 0;let n=1/0,s=-1/0,o=1/0,i=-1/0;for(const e of t.regions){const t=e;t.d?.bounds?(n=Math.min(n,t.d.bounds.minX),s=Math.max(s,t.d.bounds.maxX),o=Math.min(o,t.d.bounds.minY),i=Math.max(i,t.d.bounds.maxY)):t.d?.center&&(n=Math.min(n,t.d.center.x),s=Math.max(s,t.d.center.x),o=Math.min(o,t.d.center.y),i=Math.max(i,t.d.center.y))}const r=new Map;for(const e of t.regions){const t=e;t.d?.center&&r.set(e.regionId,t.d.center)}const a=[],c=2*(s-n)+2*(i-o);for(const t of e){let e,c;if("startRegion"in t&&t.startRegion){const n=t.startRegion,s=t.endRegion;e=n.d?.center,c=s.d?.center}else"startRegionId"in t&&(e=r.get(t.startRegionId),c=r.get(t.endRegionId));if(!e||!c)continue;const h=Eo(e,n,s,o,i),l=Eo(c,n,s,o,i);a.push([h,l])}let h=0;for(let t=0;t<a.length;t++)for(let e=t+1;e<a.length;e++)Xo(a[t],a[e],c)&&h++;return h}var $o=(t,e)=>{const n={arrows:[],circles:[],title:"Jumper Graph",lines:[],points:[],rects:[],texts:[],polygons:[],coordinateSystem:"cartesian"};for(const e of t.regions){const{bounds:t,isPad:s,isThroughJumper:o,isConnectionRegion:i,polygon:r}=e.d,a=(t.minX+t.maxX)/2,c=(t.minY+t.maxY)/2,h=t.maxX-t.minX,l=t.maxY-t.minY;let d;if(d=i?"rgba(255, 100, 255, 0.6)":o?"rgba(100, 200, 100, 0.5)":s?"rgba(255, 200, 100, 0.5)":"rgba(200, 200, 255, 0.1)",r&&r.length>=3){const t=r;n.polygons.push({points:t,fill:d})}else n.rects.push({center:{x:a,y:c},width:h-.1,height:l-.1,fill:d})}if(!e?.hidePortPoints)for(const e of t.ports){const t=e.region1.regionId.split(":").pop()??e.region1.regionId,s=e.region2.regionId.split(":").pop()??e.region2.regionId;n.circles.push({center:{x:e.d.x,y:e.d.y},radius:.05,fill:"rgba(128, 128, 128, 0.5)",label:`${t}-${s}`})}if(!e?.hideRegionPortLines)for(const e of t.ports){const t={x:(e.region1.d.bounds.minX+e.region1.d.bounds.maxX)/2,y:(e.region1.d.bounds.minY+e.region1.d.bounds.maxY)/2},s={x:(e.region2.d.bounds.minX+e.region2.d.bounds.maxX)/2,y:(e.region2.d.bounds.minY+e.region2.d.bounds.maxY)/2};n.lines.push({points:[t,{x:e.d.x,y:e.d.y},s],strokeColor:"rgba(100, 100, 100, 0.3)"})}if(e?.connections&&!e?.hideConnectionLines)for(const t of e.connections){const e=t.startRegion,s=t.endRegion,o={x:(e.d.bounds.minX+e.d.bounds.maxX)/2,y:(e.d.bounds.minY+e.d.bounds.maxY)/2},i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r=(o.x+i.x)/2,a=(o.y+i.y)/2;n.lines.push({points:[o,i],strokeColor:"rgba(255, 50, 150, 0.8)",strokeDash:"3 3"}),n.points.push({x:r,y:a,color:"rgba(200, 0, 100, 1)",label:t.connectionId})}return n},Bo=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},jo=.034685181009478865,Wo=0,Ho=4.072520483177124,Uo=0,Vo=35.38577539020022,Go=.5518001238069296,Zo=class extends go{getSolverName(){return"JumperGraphSolver"}UNIT_OF_COST="hops";portUsagePenalty=jo;portUsagePenaltySq=Wo;crossingPenalty=Ho;crossingPenaltySq=Uo;ripCost=Vo;baseMaxIterations=4e3;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Go,rippingEnabled:!0,...t}),this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=ko(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}isTransitionAllowed(t,e,n){if(!t.d.isPad)return!0;const s=e=>{const n=e.region1===t?e.region2:e.region1;return Boolean(n.d.isThroughJumper)};return s(e)||s(n)}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isPad){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=Oo(t),o=[Ao(e,t),Ao(n,t)];let i=0;const r=t.assignments??[];for(const e of r)Xo(o,[Ao(e.regionPort1,t),Ao(e.regionPort2,t)],s)&&i++;return i}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}getRipsRequiredForPortUsage(t,e,n){if(t.d.isPad){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=Oo(t),o=[Ao(e,t),Ao(n,t)],i=[],r=t.assignments??[];for(const e of r)Xo(o,[Ao(e.regionPort1,t),Ao(e.regionPort2,t)],s)&&i.push(e);return i}(t,e,n),o=s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId);if(!t.d.isThroughJumper)return o;for(const e of t.assignments??[])e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId&&o.push(e);return o}isRipRequiredForPortUsage(t,e,n){if(!t.d.isThroughJumper&&!t.d.isPad)return!1;for(const e of t.assignments??[])if(e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)return!0;return!1}routeSolvedHook(t){}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=$o(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;if(t.currentConnection&&!t.solved){const e=Bo(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const t=Bo(e.connection.connectionId),s=[];for(const t of e.path){const e=t.port;s.push({x:e.d.x,y:e.d.y})}s.length>0&&n.lines.push({points:s,strokeColor:t})}const s=t.candidateQueue.peekMany(10);for(let t=0;t<s.length;t++){const e=s[t],o=e.port,i=0===t;n.points.push({x:o.d.x,y:o.d.y,color:i?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const o=s[0];if(!t.solved&&o&&t.currentConnection){const e=Bo(t.currentConnection.connectionId),s=[];let i=o;for(;i;){const t=i.port;s.unshift({x:t.d.x,y:t.d.y}),i=i.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}return n})(this)}},qo=(t,e,n,s)=>{const o={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(o),n.ports.push(o),o},Jo=(t,e,n)=>{const s=.2;return{regionId:t,ports:[],d:{bounds:{minX:e-s,maxX:e+s,minY:n-s,maxY:n+s},center:{x:e,y:n},isPad:!1,isConnectionRegion:!0}}},Ko=.01,Qo=(t,e,n)=>Math.max(e,Math.min(n,t)),ti=(t,e,n)=>"left"===e?Math.abs(t.x-n.minX)<Ko:"right"===e?Math.abs(t.x-n.maxX)<Ko:"top"===e?Math.abs(t.y-n.maxY)<Ko:Math.abs(t.y-n.minY)<Ko,ei=(t,e,n,s)=>{const o=s.x-n.x,i=s.y-n.y,r=t-n.x,a=e-n.y,c=o*o+i*i,h=c>0?Qo((r*o+a*i)/c,0,1):0,l=n.x+h*o,d=n.y+h*i,u=t-l,p=e-d;return{x:l,y:d,d2:u*u+p*p}},ni=(t,e,n,s,o)=>{const i=n.d.polygon;if(i&&i.length>=3){const n=new Set(o);let r=null;for(let a=0;a<i.length;a++){const c=i[a],h=i[(a+1)%i.length];if(o.length>0){if(!o.some(t=>ti(c,t,s)&&ti(h,t,s)&&n.has(t)))continue}const l=ei(t,e,c,h);(!r||l.d2<r.d2)&&(r=l)}if(r)return r}const r=n.d.bounds,a=[];if(o.length>0)for(const n of o)"left"===n?a.push({side:n,x:r.minX,y:Qo(e,r.minY,r.maxY)}):"right"===n?a.push({side:n,x:r.maxX,y:Qo(e,r.minY,r.maxY)}):"top"===n?a.push({side:n,x:Qo(t,r.minX,r.maxX),y:r.maxY}):a.push({side:n,x:Qo(t,r.minX,r.maxX),y:r.minY});0===a.length&&a.push({side:"left",x:r.minX,y:Qo(e,r.minY,r.maxY)},{side:"right",x:r.maxX,y:Qo(e,r.minY,r.maxY)},{side:"top",x:Qo(t,r.minX,r.maxX),y:r.maxY},{side:"bottom",x:Qo(t,r.minX,r.maxX),y:r.minY});let c=null;for(const n of a){if(o.length>0&&!o.includes(n.side))continue;const s=t-n.x,i=e-n.y,r=s*s+i*i;(!c||r<c.d2)&&(c={x:n.x,y:n.y,d2:r})}return c},si=(t,e,n,s)=>{const o=((t,e,n)=>{const s=[];return Math.abs(t-n.minX)<Ko&&s.push("left"),Math.abs(t-n.maxX)<Ko&&s.push("right"),Math.abs(e-n.maxY)<Ko&&s.push("top"),Math.abs(e-n.minY)<Ko&&s.push("bottom"),s})(t,e,s);let i=null,r=Number.POSITIVE_INFINITY,a={x:t,y:e};for(const c of n){if(c.d.isPad||c.d.isThroughJumper)continue;const n=c.d.bounds;if(!(Math.abs(n.minX-s.minX)<.01||Math.abs(n.maxX-s.maxX)<.01||Math.abs(n.minY-s.minY)<.01||Math.abs(n.maxY-s.maxY)<.01))continue;const h=ni(t,e,c,s,o);if(!h)continue;const l=Math.sqrt(h.d2);l<r&&(r=l,i=c,a={x:h.x,y:h.y})}return i?{region:i,portPosition:a}:null},oi={padWidth:.8,outerPadHeight:.5,innerPadHeight:.4,leftPadCenterX:-.9,rightPadCenterX:.9,row1CenterY:-1.2,row2CenterY:-.4,row3CenterY:.4,row4CenterY:1.2},ii=({cols:t,rows:e,marginX:n,marginY:s,innerColChannelPointCount:o=1,innerRowChannelPointCount:i=1,regionsBetweenPads:r=!1,outerPaddingX:a=.5,outerPaddingY:c=.5,outerChannelXPointCount:h,outerChannelYPointCount:l,orientation:d="vertical",center:u,bounds:p,parallelTracesUnderJumperCount:f=2})=>{const m=[],g=[],{padWidth:y,outerPadHeight:x,innerPadHeight:v,leftPadCenterX:b,rightPadCenterX:P,row1CenterY:S,row2CenterY:M,row3CenterY:N,row4CenterY:I}=oi,_=y/2,C=x/2,T=v/2,E=P-b+y,w=E+n,R=I-S+x,O=R+s;let A=a,z=c;if(p){const o=t*E+(t-1)*n,i=e*R+(e-1)*s;A=(("horizontal"===d?p.maxY-p.minY:p.maxX-p.minX)-o)/2,z=(("horizontal"===d?p.maxX-p.minX:p.maxY-p.minY)-i)/2}const L=h??Math.max(1,Math.floor(A/.4)),D=l??Math.max(1,Math.floor(z/.4)),F=[],Y=[],X=(t,e,n,s)=>({regionId:t,ports:[],d:{bounds:e,center:_o(e),isPad:n,isThroughJumper:s}}),k=(t,e,n)=>{const s=e.d.bounds,o=n.d.bounds;let i,r;Math.abs(s.maxX-o.minX)<.001?(i=s.maxX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.minX-o.maxX)<.001?(i=s.minX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.maxY-o.minY)<.001?(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.maxY):(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.minY);const a={portId:t,region1:e,region2:n,d:{x:i,y:r}};return e.ports.push(a),n.ports.push(a),a},$=(t,e,n,s)=>{if(s<=0)return[];if(1===s)return[k(t,e,n)];const o=e.d.bounds,i=n.d.bounds,r=[];let a,c,h,l;Math.abs(o.maxX-i.minX)<.001?(a=!0,c=o.maxX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.minX-i.maxX)<.001?(a=!0,c=o.minX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.maxY-i.minY)<.001?(a=!1,c=o.maxY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX)):(a=!1,c=o.minY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX));for(let o=0;o<s;o++){const i=h+(o+.5)/s*(l-h),d={portId:`${t}:${o}`,region1:e,region2:n,d:{x:a?c:i,y:a?i:c}};e.ports.push(d),n.ports.push(d),r.push(d)}return r};for(let n=0;n<e;n++){F[n]=[];for(let a=0;a<t;a++){const c=`cell_${n}_${a}`,h=a*w,l=-n*O,d=h+b,u=l+S,p=h+b,y=l+M,x=h+b,v=l+N,E=h+b,R=l+I,B=h+P,j=l+I,W=h+P,H=l+N,U=h+P,V=l+M,G=h+P,Z=l+S,q=(t,e,n)=>({minX:t-_,maxX:t+_,minY:e-n,maxY:e+n}),J=q(d,u,C),K=q(p,y,T),Q=q(x,v,T),tt=q(E,R,C),et=q(B,j,C),nt=q(W,H,T),st=q(U,V,T),ot=q(G,Z,C),it={minX:J.maxX,maxX:ot.minX,minY:J.minY,maxY:tt.maxY},rt=.3,at={minX:d,maxX:G,minY:u-rt/2,maxY:u+rt/2},ct={minX:p,maxX:U,minY:y-rt/2,maxY:y+rt/2},ht={minX:x,maxX:W,minY:v-rt/2,maxY:v+rt/2},lt={minX:E,maxX:B,minY:R-rt/2,maxY:R+rt/2},dt=J.minX,ut=ot.maxX,pt=J.minY,ft=tt.maxY,mt=X(`${c}:pad1`,J,!0),gt=X(`${c}:pad2`,K,!0),yt=X(`${c}:pad3`,Q,!0),xt=X(`${c}:pad4`,tt,!0),vt=X(`${c}:pad5`,et,!0),bt=X(`${c}:pad6`,nt,!0),Pt=X(`${c}:pad7`,st,!0),St=X(`${c}:pad8`,ot,!0),Mt=X(`${c}:underjumper`,it,!1),Nt=X(`${c}:throughjumper1`,at,!1,!0),It=X(`${c}:throughjumper2`,ct,!1,!0),_t=X(`${c}:throughjumper3`,ht,!1,!0),Ct=X(`${c}:throughjumper4`,lt,!1,!0);m.push(mt,gt,yt,xt,vt,bt,Pt,St,Mt,Nt,It,_t,Ct);const Tt=(d+G)/2,Et=(u+R)/2;Y.push({center:{x:Tt,y:Et},orientation:"vertical",padRegions:[mt,gt,yt,xt,vt,bt,Pt,St]});let wt=null,Rt=null,Ot=null,At=null,zt=null,Lt=null;r&&(wt=X(`${c}:L-BP12`,{minX:J.minX,maxX:J.maxX,minY:J.maxY,maxY:K.minY},!1),Rt=X(`${c}:L-BP23`,{minX:K.minX,maxX:K.maxX,minY:K.maxY,maxY:Q.minY},!1),Ot=X(`${c}:L-BP34`,{minX:Q.minX,maxX:Q.maxX,minY:Q.maxY,maxY:tt.minY},!1),At=X(`${c}:R-BP87`,{minX:ot.minX,maxX:ot.maxX,minY:ot.maxY,maxY:st.minY},!1),zt=X(`${c}:R-BP76`,{minX:st.minX,maxX:st.maxX,minY:st.maxY,maxY:nt.minY},!1),Lt=X(`${c}:R-BP65`,{minX:nt.minX,maxX:nt.maxX,minY:nt.maxY,maxY:et.minY},!1),m.push(wt,Rt,Ot,At,zt,Lt));const Dt=0===a,Ft=n===e-1,Yt=a===t-1;let Xt;if(Yt)Xt=ut+A;else{Xt=(a+1)*w+b-_}let kt=null;0===n&&(kt=X(`${c}:T`,{minX:Dt?dt-A:dt,maxX:Xt,minY:ft,maxY:ft+z},!1),m.push(kt));let $t=null;$t=X(`${c}:B`,{minX:Dt?dt-A:dt,maxX:Xt,minY:pt-(Ft?z:s),maxY:pt},!1),m.push($t);let Bt=null;Dt&&(Bt=X(`${c}:L`,{minX:dt-A,maxX:dt,minY:pt,maxY:ft},!1),m.push(Bt));const jt=X(`${c}:R`,{minX:ut,maxX:Xt,minY:pt,maxY:ft},!1);if(m.push(jt),F[n][a]={pad1:mt,pad2:gt,pad3:yt,pad4:xt,pad5:vt,pad6:bt,pad7:Pt,pad8:St,underjumper:Mt,throughjumper1:Nt,throughjumper2:It,throughjumper3:_t,throughjumper4:Ct,top:kt,bottom:$t,left:Bt,right:jt,leftBP12:wt,leftBP23:Rt,leftBP34:Ot,rightBP87:At,rightBP76:zt,rightBP65:Lt},kt)if(Bt&&g.push(...$(`${c}:T-L`,kt,Bt,L)),g.push(...$(`${c}:T-R`,kt,jt,Yt?L:o)),g.push(k(`${c}:T-P4`,kt,xt)),g.push(k(`${c}:T-P5`,kt,vt)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:T-UJ${n}`,region1:kt,region2:Mt,d:{x:t.minX+e*n,y:t.maxY}};kt.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:T-UJ`,kt,Mt));if($t)if(Bt&&g.push(...$(`${c}:B-L`,$t,Bt,L)),g.push(...$(`${c}:B-R`,$t,jt,Yt?L:o)),g.push(k(`${c}:B-P1`,$t,mt)),g.push(k(`${c}:B-P8`,$t,St)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:B-UJ${n}`,region1:$t,region2:Mt,d:{x:t.minX+e*n,y:t.minY}};$t.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:B-UJ`,$t,Mt));Bt&&(g.push(k(`${c}:L-P1`,Bt,mt)),g.push(k(`${c}:L-P2`,Bt,gt)),g.push(k(`${c}:L-P3`,Bt,yt)),g.push(k(`${c}:L-P4`,Bt,xt))),g.push(k(`${c}:R-P5`,jt,vt)),g.push(k(`${c}:R-P6`,jt,bt)),g.push(k(`${c}:R-P7`,jt,Pt)),g.push(k(`${c}:R-P8`,jt,St)),r&&(Bt&&(g.push(k(`${c}:L-BP12`,Bt,wt)),g.push(k(`${c}:L-BP23`,Bt,Rt)),g.push(k(`${c}:L-BP34`,Bt,Ot))),g.push(k(`${c}:UJ-LBP12`,wt,Mt)),g.push(k(`${c}:UJ-LBP23`,Rt,Mt)),g.push(k(`${c}:UJ-LBP34`,Ot,Mt)),g.push(k(`${c}:R-BP87`,jt,At)),g.push(k(`${c}:R-BP76`,jt,zt)),g.push(k(`${c}:R-BP65`,jt,Lt)),g.push(k(`${c}:UJ-RBP87`,At,Mt)),g.push(k(`${c}:UJ-RBP76`,zt,Mt)),g.push(k(`${c}:UJ-RBP65`,Lt,Mt)));const Wt={portId:`${c}:TJ1-P1`,region1:Nt,region2:mt,d:{x:d,y:u}};Nt.ports.push(Wt),mt.ports.push(Wt),g.push(Wt);const Ht={portId:`${c}:TJ1-P8`,region1:Nt,region2:St,d:{x:G,y:Z}};Nt.ports.push(Ht),St.ports.push(Ht),g.push(Ht);const Ut={portId:`${c}:TJ2-P2`,region1:It,region2:gt,d:{x:p,y:y}};It.ports.push(Ut),gt.ports.push(Ut),g.push(Ut);const Vt={portId:`${c}:TJ2-P7`,region1:It,region2:Pt,d:{x:U,y:V}};It.ports.push(Vt),Pt.ports.push(Vt),g.push(Vt);const Gt={portId:`${c}:TJ3-P3`,region1:_t,region2:yt,d:{x:x,y:v}};_t.ports.push(Gt),yt.ports.push(Gt),g.push(Gt);const Zt={portId:`${c}:TJ3-P6`,region1:_t,region2:bt,d:{x:W,y:H}};_t.ports.push(Zt),bt.ports.push(Zt),g.push(Zt);const qt={portId:`${c}:TJ4-P4`,region1:Ct,region2:xt,d:{x:E,y:R}};Ct.ports.push(qt),xt.ports.push(qt),g.push(qt);const Jt={portId:`${c}:TJ4-P5`,region1:Ct,region2:vt,d:{x:B,y:j}};if(Ct.ports.push(Jt),vt.ports.push(Jt),g.push(Jt),a>0){const t=F[n][a-1];g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P1`,t.right,mt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P2`,t.right,gt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P3`,t.right,yt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P4`,t.right,xt)),r&&(g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP12`,t.right,wt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP23`,t.right,Rt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP34`,t.right,Ot))),kt&&t.top&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:T-T`,t.top,kt,D)),$t&&t.bottom&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:B-B`,t.bottom,$t,Ft?D:i))}if(n>0){const t=F[n-1][a];if(Bt&&g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-L`,t.bottom,Bt,L)),g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P4`,t.bottom,xt)),r){const e=Mt.d.bounds,s=(e.maxX-e.minX)/(f+1);for(let o=1;o<=f;o++){const i=e.minX+s*o,r={portId:`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ${o}`,region1:t.bottom,region2:Mt,d:{x:i,y:e.maxY}};t.bottom.ports.push(r),Mt.ports.push(r),g.push(r)}}else g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ`,t.bottom,Mt));g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P5`,t.bottom,vt)),g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-R`,t.bottom,jt,Yt?L:o))}}}let B={regions:m,ports:g,jumperLocations:Y};const j="horizontal"===d;if(j||void 0!==u||void 0!==p){const t=Io(B.regions),e=_o(t),n=[];let s;s=u||(p?_o(p):e),n.push(vo(s.x,s.y)),j&&n.push(function(t,e,n){const s=Po(t),o=So(t),i={a:s,c:-o,e:0,b:o,d:s,f:0};return xo(e)||xo(n)?i:bo([vo(e,n),i,vo(-e,-n)])}(-Math.PI/2)),n.push(vo(-e.x,-e.y));const o=function(...t){return bo(...t)}(...n);B=Co(B,o)}return B},ri={viasByNet:{net1:[{viaId:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",diameter:.3,position:{x:.815244,y:-.055081}},{viaId:"8a898812-db2b-4b81-899d-f953b3222f9a",diameter:.3,position:{x:-.528763,y:.676055}}],net3:[{viaId:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",diameter:.3,position:{x:-.808222,y:-.726499}},{viaId:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",diameter:.3,position:{x:.901143,y:.437488}}],net4:[{viaId:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",diameter:.3,position:{x:-.029,y:.691542}},{viaId:"37a70467-7553-415f-8ad7-8b88a5e56ca8",diameter:.3,position:{x:-.824388,y:.272808}},{viaId:"6d182b7d-a260-427b-8c43-a09409422252",diameter:.3,position:{x:.083422,y:-.705274}}],net5:[{viaId:"346c301a-f2b4-44d7-b975-5438ddaa0bde",diameter:.3,position:{x:.517145,y:-.456503}},{viaId:"c54b4b94-90e0-4240-97ef-883cf097d79d",diameter:.3,position:{x:.471002,y:.692404}},{viaId:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",diameter:.3,position:{x:-.833162,y:-.227118}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",toPort:"8a898812-db2b-4b81-899d-f953b3222f9a",layer:"bottom",segments:[{x:.815244,y:-.055081},{x:1.01282,y:-.252657},{x:1.01282,y:-.563283},{x:.444829,y:-1.131274},{x:-.093033,y:-1.131274},{x:-.382222,y:-.842085},{x:-.382222,y:.433097},{x:-.528763,y:.579638},{x:-.528763,y:.676055}]},{routeId:"net3:route_0",fromPort:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",toPort:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",layer:"bottom",segments:[{x:-.808222,y:-.726499},{x:-.808222,y:-.912474},{x:-.238422,y:-1.482274},{x:.590217,y:-1.482274},{x:1.36382,y:-.708672},{x:1.36382,y:-.001202},{x:.92513,y:.437488},{x:.901143,y:.437488}]},{routeId:"net4:route_0",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"6d182b7d-a260-427b-8c43-a09409422252",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:-.592852},{x:.083422,y:-.705274}]},{routeId:"net4:route_1",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"37a70467-7553-415f-8ad7-8b88a5e56ca8",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:.778747},{x:-.352308,y:1.102055},{x:-.705218,y:1.102055},{x:-.954763,y:.85251},{x:-.954763,y:.403183},{x:-.824388,y:.272808}]},{routeId:"net5:route_0",fromPort:"346c301a-f2b4-44d7-b975-5438ddaa0bde",toPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",layer:"bottom",segments:[{x:.517145,y:-.456503},{x:.389244,y:-.328602},{x:.389244,y:.610646},{x:.471002,y:.692404}]},{routeId:"net5:route_1",fromPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",toPort:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",layer:"bottom",segments:[{x:.471002,y:.692404},{x:.471002,y:1.111132},{x:.129079,y:1.453055},{x:-.850606,y:1.453055},{x:-1.305763,y:.997899},{x:-1.305763,y:.151728},{x:-.926917,y:-.227118},{x:-.833162,y:-.227118}]}],tileWidth:2.9695829999999996,tileHeight:3.2353289999999997};function ai(t,e,n,s,o,i,r){return!!Xo(t,e,n)||function(t,e,n,s,o=1e-9){const i=(t,e)=>Math.abs(t.x-e.x)<o&&Math.abs(t.y-e.y)<o;if(i(t,n)||i(t,s)||i(e,n)||i(e,s))return!1;const r=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),a=r(n,s,t),c=r(n,s,e),h=r(t,e,n),l=r(t,e,s);if(a*c<0&&h*l<0)return!0;const d=(t,e,n,s)=>{if(Math.abs(s)>o)return!1;const i=Math.min(e.x,n.x)-o,r=Math.max(e.x,n.x)+o,a=Math.min(e.y,n.y)-o,c=Math.max(e.y,n.y)+o;return t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c};return!((!d(t,n,s,a)||i(t,n)||i(t,s))&&(!d(e,n,s,c)||i(e,n)||i(e,s))&&(!d(n,t,e,h)||i(n,t)||i(n,e))&&(!d(s,t,e,l)||i(s,t)||i(s,e)))}(s.d,o.d,i.d,r.d)}var ci=1e-6;function hi(t,e){return Math.abs(t.x-e.x)<=ci&&Math.abs(t.y-e.y)<=ci}function li(t,e){const n=t[t.length-1];n&&hi(n,e)||t.push(e)}function di(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=Math.hypot(t,i);r<s&&(s=r,n=o)}return n}function ui(t,e){const n=new Set(e.map(t=>t.viaId));return t.routeSegments.filter(t=>"bottom"===t.layer&&n.has(t.fromPort)&&n.has(t.toPort)&&t.segments.length>=2)}function pi(t,e){const n=function(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=function(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}function fi(t,e,n){const s=function(t){const e=[];for(const n of t)li(e,n);return e}(e);if(s.length<2)return;const o=t[t.length-1];if(!o||o.layer!==n)return void t.push({points:s,layer:n});const i=o.points[o.points.length-1],r=s[0];if(!i||!r||!hi(i,r))return void t.push({points:s,layer:n});const a=s.slice(1);for(const t of a)li(o.points,t)}function mi(t,e){if(0===t.path.length)return[];const n=t.path,s=[],o=new Set;for(let t=1;t<n.length;t++){const i=n[t-1],r=n[t],a={x:i.port.d.x,y:i.port.d.y},c={x:r.port.d.x,y:r.port.d.y},h=r.lastRegion;if(!(!!e&&!!h?.d?.isViaRegion)){fi(s,[a,c],"top");continue}const l=pi(e,h);if(0===l.length)continue;const d=di(l,a),u=di(l,c);d&&fi(s,[a,d.position],"top");const p=ui(e,l);if(p.length>0&&!o.has(h.regionId)){o.add(h.regionId);for(const t of p)fi(s,t.segments,"bottom")}u&&fi(s,[u.position,c],"top")}return s}function gi(t,e){return function(t){const e=[];for(const n of t)for(const t of n.points)li(e,t);return e}(mi(t,e))}var yi=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},xi=["rgba(231, 76, 60, 0.35)","rgba(46, 204, 113, 0.35)","rgba(52, 152, 219, 0.35)","rgba(243, 156, 18, 0.35)","rgba(155, 89, 182, 0.35)","rgba(26, 188, 156, 0.35)","rgba(241, 196, 15, 0.35)","rgba(230, 126, 34, 0.35)"],vi=.034685181009478865,bi=0,Pi=4.072520483177124,Si=0,Mi=35.38577539020022,Ni=.5518001238069296,Ii=class extends go{getSolverName(){return"ViaGraphSolver"}UNIT_OF_COST="hops";viaTile;portUsagePenalty=vi;portUsagePenaltySq=bi;crossingPenalty=Pi;crossingPenaltySq=Si;ripCost=Mi;baseMaxIterations=9e5;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Ni,rippingEnabled:!0,...t}),this.viaTile=t.viaTile,this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=ko(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isViaRegion){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return 0;const o=Oo(t),i=[Ao(e,t),Ao(n,t)];let r=0;const a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;ai(i,[Ao(a,t),Ao(c,t)],o,e,n,a,c)&&r++}return r}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}isRipRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).some(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}return!1}getRipsRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return[];const o=Oo(t),i=[Ao(e,t),Ao(n,t)],r=[],a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;ai(i,[Ao(a,t),Ao(c,t)],o,e,n,a,c)&&r.push(s)}return r}(t,e,n);return s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}routeSolvedHook(t){}getSolvedRoutePoints(t){return gi(t,this.viaTile)}getSolvedRouteLineSegments(t){return mi(t,this.viaTile)}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=$o(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;const s=new Set(["T","B","L","R"]);let o=0;const i=new Map;let r=0;for(const t of e.regions){const e=t;if(!(e.d.polygon&&e.d.polygon.length>=3))continue;const a=e.regionId.split(":").pop()??"";s.has(a)||e.d.isConnectionRegion||(i.has(a)||(i.set(a,xi[o%xi.length]),o++),n.polygons[r]&&(n.polygons[r].fill=i.get(a))),r++}if(t.currentConnection&&!t.solved){const e=yi(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const s=yi(e.connection.connectionId),o=t.getSolvedRouteLineSegments(e);for(const t of o){const e="bottom"===t.layer;n.lines.push({points:t.points,strokeColor:e?"rgba(52, 152, 219, 0.95)":s,...e?{strokeDash:"3 2"}:{}})}}const a=t.candidateQueue.peekMany(10);for(let t=0;t<a.length;t++){const e=a[t],s=e.port,o=0===t;n.points.push({x:s.d.x,y:s.d.y,color:o?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const c=a[0];if(!t.solved&&c&&t.currentConnection){const e=yi(t.currentConnection.connectionId),s=[];let o=c;for(;o;){const t=o.port;s.unshift({x:t.d.x,y:t.d.y}),o=o.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}if(t.viaTile){n.circles||(n.circles=[]);for(const[e,s]of Object.entries(t.viaTile.viasByNet)){const t=i.get(e),o=t?t.replace("0.35","0.5"):"rgba(255, 0, 0, 0.3)";for(const t of s)n.circles.push({center:t.position,radius:t.diameter/2,fill:o,label:e})}}return n})(this)}};function _i(t,e){let n=1/0,s={x:t.x,y:t.y};for(let o=0;o<e.length;o++){const i=e[o],r=e[(o+1)%e.length],a=r.x-i.x,c=r.y-i.y,h=a*a+c*c;if(h<1e-10)continue;const l=Math.max(0,Math.min(1,((t.x-i.x)*a+(t.y-i.y)*c)/h)),d=i.x+l*a,u=i.y+l*c,p=Math.sqrt((t.x-d)**2+(t.y-u)**2);p<n&&(n=p,s={x:d,y:u})}return{...s,dist:n}}var Ci=t=>{const{x:e,y:n,regions:s}=t,o=s.some(t=>t.regionId.startsWith("filler:"));let i=null,r=1/0,a={x:e,y:n};for(const t of s){if(t.d.isPad||t.d.isThroughJumper||t.d.isConnectionRegion)continue;if(o&&!t.regionId.startsWith("filler:"))continue;const s=t.d.polygon;if(!s||s.length<3)continue;const c=_i({x:e,y:n},s);c.dist<r&&(r=c.dist,i=t,a={x:c.x,y:c.y})}return i?{region:i,portPosition:a}:null},Ti=!0,Ei={CCW:-1,CW:1,NOT_ORIENTABLE:0},wi=2*Math.PI,Ri=Object.freeze({__proto__:null,BOUNDARY:2,CCW:Ti,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:Ei,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:wi,START_VERTEX:1}),Oi=1e-6;function Ai(t){Oi=t}function zi(){return Oi}function Li(t){return t<Oi&&t>-Oi}function Di(t,e){return t-e<Oi&&t-e>-Oi}function Fi(t,e){return t-e>Oi}function Yi(t,e){return t-e<-Oi}var Xi={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:Di,EQ_0:Li,GE:function(t,e){return t-e>-Oi},GT:Fi,LE:function(t,e){return t-e<Oi},LT:Yi,getTolerance:zi,setTolerance:Ai}),Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let t in Ri)Xi[t]=Ri[t];Object.defineProperty(Xi,"DP_TOL",{get:function(){return zi()},set:function(t){Ai(t)}});var ki=class{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}};Xi.Errors=ki;var $i=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:void 0===t})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],s=t||this.first,o=e||this.last,i=s;if(void 0===i)return n;do{n.push(i),i=i.next}while(i!==o.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(null==e)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw ki.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},Bi={stroke:"black"},ji=class{constructor(t=Bi){for(const e in t)this[e]=t[e];this.stroke=t.stroke??Bi.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(void 0!==this[e]?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n="className"===t?"class":this.convertCamelToKebabCase(t);return null===e?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}};function Wi(t){return new ji(t).toAttributesString()}function Hi(t,e){let n=[],[s,o,i]=t.standard,[r,a,c]=e.standard,h=s*a-o*r,l=i*a-o*c,d=s*c-i*r;if(!Xi.Utils.EQ_0(h)){let t,e;0===o?(t=i/s,e=d/h):0===a?(t=c/r,e=d/h):0===s?(t=l/h,e=i/o):0===r?(t=l/h,e=c/a):(t=l/h,e=d/h),n.push(new Xi.Point(t,e))}return n}function Ui(t,e){let n=[],s=e.pc.projectionOn(t),o=e.pc.distanceTo(s)[0];if(Xi.Utils.EQ(o,e.r))n.push(s);else if(Xi.Utils.LT(o,e.r)){let i,r,a=Math.sqrt(e.r*e.r-o*o);i=t.norm.rotate90CCW().multiply(a),r=s.translate(i),n.push(r),i=t.norm.rotate90CW().multiply(a),r=s.translate(i),n.push(r)}return n}function Vi(t,e){let n=[];for(let s of e.toSegments()){let e=Zi(s,t);for(let t of e)pr(t,n)||n.push(t)}return n}function Gi(t,e){let n=[];if(0===Vi(t,e.box).length)return n;let s=Ui(t,new Xi.Circle(e.pc,e.r));for(let t of s)t.on(e)&&n.push(t);return n}function Zi(t,e){let n=[];return t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&!t.isZeroLength()&&n.push(t.pe),n.length>0||t.isZeroLength()||t.ps.leftTo(e)&&t.pe.leftTo(e)||!t.ps.leftTo(e)&&!t.pe.leftTo(e)?n:Hi(new Xi.Line(t.ps,t.pe),e)}function qi(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)&&n.push(e.ps),n;let s=new Xi.Line(t.ps,t.pe),o=new Xi.Line(e.ps,e.pe);if(s.incidentTo(o))t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&n.push(t.pe),!e.ps.on(t)||e.ps.equalTo(t.ps)||e.ps.equalTo(t.pe)||n.push(e.ps),!e.pe.on(t)||e.pe.equalTo(t.ps)||e.pe.equalTo(t.pe)||n.push(e.pe);else{let i=Hi(s,o);i.length>0&&Ji(i[0],t)&&Ji(i[0],e)&&n.push(i[0])}return n}function Ji(t,e){const n=e.box;return Xi.Utils.LE(t.x,n.xmax)&&Xi.Utils.GE(t.x,n.xmin)&&Xi.Utils.LE(t.y,n.ymax)&&Xi.Utils.GE(t.y,n.ymin)}function Ki(t,e){let n=[];if(t.isZeroLength()){let[s,o]=t.ps.distanceTo(e.pc);return Xi.Utils.EQ(s,e.r)&&n.push(t.ps),n}let s=Ui(new Xi.Line(t.ps,t.pe),e);for(let e of s)e.on(t)&&n.push(e);return n}function Qi(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let s=Ui(new Xi.Line(t.ps,t.pe),new Xi.Circle(e.pc,e.r));for(let o of s)o.on(t)&&o.on(e)&&n.push(o);return n}function tr(t,e){let n=[],s=new Xi.Vector(t.pc,e.pc),o=t.r,i=e.r;if(Xi.Utils.EQ_0(o)||Xi.Utils.EQ_0(i))return n;if(Xi.Utils.EQ_0(s.x)&&Xi.Utils.EQ_0(s.y)&&Xi.Utils.EQ(o,i))return n.push(t.pc.translate(-o,0)),n;let r,a=t.pc.distanceTo(e.pc)[0];if(Xi.Utils.GT(a,o+i))return n;if(Xi.Utils.LT(a,Math.abs(o-i)))return n;if(s.x/=a,s.y/=a,Xi.Utils.EQ(a,o+i)||Xi.Utils.EQ(a,Math.abs(o-i)))return r=t.pc.translate(o*s.x,o*s.y),n.push(r),n;let c=o*o/(2*a)-i*i/(2*a)+a/2,h=t.pc.translate(c*s.x,c*s.y),l=Math.sqrt(o*o-c*c);return r=h.translate(s.rotate90CCW().multiply(l)),n.push(r),r=h.translate(s.rotate90CW().multiply(l)),n.push(r),n}function er(t,e){let n=[];if(t.pc.equalTo(e.pc)&&Xi.Utils.EQ(t.r,e.r)){let s;return s=t.start,s.on(e)&&n.push(s),s=t.end,s.on(e)&&n.push(s),s=e.start,s.on(t)&&n.push(s),s=e.end,s.on(t)&&n.push(s),n}let s=new Xi.Circle(t.pc,t.r),o=new Xi.Circle(e.pc,e.r),i=s.intersect(o);for(let s of i)s.on(t)&&s.on(e)&&n.push(s);return n}function nr(t,e){let n=[];if(e.pc.equalTo(t.pc)&&Xi.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let s=tr(e,new Xi.Circle(t.pc,t.r));for(let e of s)e.on(t)&&n.push(e);return n}function sr(t,e){return t.isSegment?qi(t.shape,e):Qi(e,t.shape)}function or(t,e){return t.isSegment?Qi(t.shape,e):er(t.shape,e)}function ir(t,e){return t.isSegment?Zi(t.shape,e):Gi(e,t.shape)}function rr(t,e){return t.isSegment?Ki(t.shape,e):nr(t.shape,e)}function ar(t,e){let n=[];for(let s of e.edges)for(let e of sr(s,t))n.push(e);return n}function cr(t,e){let n=[];for(let s of e.edges)for(let e of or(s,t))n.push(e);return n}function hr(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of ir(s,t))pr(e,n)||n.push(e);return t.sortPoints(n)}function lr(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of rr(s,t))n.push(e);return n}function dr(t,e){return t.isSegment?sr(e,t.shape):t.isArc?or(e,t.shape):t.isLine?ir(e,t.shape):t.isRay?(n=e,s=t.shape,n.isSegment?mr(s,n.shape):gr(s,n.shape)):[];var n,s}function ur(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let s=e.edges.search(t.shape.box);for(let e of s)n=[...n,...dr(t,e)];return n}function pr(t,e){return e.some(e=>e.equalTo(t))}function fr(t){return new Xi.Line(t.start,t.norm)}function mr(t,e){return Zi(e,fr(t)).filter(e=>t.contains(e))}function gr(t,e){return Gi(fr(t),e).filter(e=>t.contains(e))}function yr(t,e){return Ui(fr(t),e).filter(e=>t.contains(e))}function xr(t,e){return Hi(fr(t),e).filter(e=>t.contains(e))}function vr(t,e){return hr(fr(t),e).filter(e=>t.contains(e))}function br(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw ki.UNSUPPORTED_SHAPE_TYPE}function Pr(t,e){let n=[];for(let s of e)n=[...n,...br(t,s.shape)];return n}var Sr=class t extends $i{constructor(...t){if(super(),this.isInfinite=!1,1===t.length&&t[0]instanceof Array&&t[0].length>0){const e=t[0],n=e.length,s=t=>t instanceof Xi.Segment||t instanceof Xi.Arc||t instanceof Xi.Ray,o=t=>t instanceof Xi.Segment||t instanceof Xi.Arc;if(!(1===n&&(t=>t instanceof Xi.Segment||t instanceof Xi.Arc||t instanceof Xi.Ray||t instanceof Xi.Line)(e[0])||n>1&&s(e[0])&&s(e[n-1])&&e.slice(1,n-1).every(o)))throw Xi.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof Xi.Ray||t instanceof Xi.Line);for(let t of e){let e=new Xi.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new Xi.Box)}get vertices(){let t=this.edges.map(t=>t.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let e of this)t+=e.length;return t}clone(){return new t(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new Xi.Edge(n[0]),o=e.prev;return this.insert(s,o),e.shape=n[1],s}getChain(t,e){let n=[];for(let s=t;s!==e.next;s=s.next)n.push(s);return n}split(t){for(let e of t){let t=this.findEdgeByPoint(e);this.addVertex(e,t)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}distanceTo(t){if(t instanceof Point){const[e,n]=Xi.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Xi.Line){const[e,n]=Xi.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Xi.Circle){const[e,n]=Xi.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Xi.Segment){const[e,n]=Xi.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Xi.Arc){const[e,n]=Xi.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Xi.Multiline)return Xi.Distance.multiline2multiline(this,t);throw Xi.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof Xi.Multiline?function(t,e){let n=[];for(let s of t)for(let t of e)n=[...n,...br(s.shape,t.shape)];return n}(this,t):Pr(t,this)}contains(t){if(t instanceof Xi.Point)return this.edges.some(e=>e.shape.contains(t));throw Xi.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new Xi.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new Xi.Matrix){return new t(this.edges.map(t=>t.shape.transform(e)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t}svg(t={}){let e=`\n<path ${Wi({fill:"none",...t})} d="`;e+=`\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='" >\n</path>',e}};Xi.Multiline=Sr;function Mr(t,e,n){let s=n.length,o=t.shape.split(e);if(0===o.length)return;let i=0;i=null===o[0]?0:null===o[1]?t.shape.length:o[0].length;let r,a=0;Di(i,0)&&(a|=1),Di(i,t.shape.length)&&(a|=2),r=i===1/0?o[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+i,n.push({id:s,pt:e,arc_length:r,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function Nr(t){t.int_points1_sorted=Ir(t.int_points1),t.int_points2_sorted=Ir(t.int_points2)}function Ir(t){let e=new Map,n=0;for(let s of t)e.has(s.face)||(e.set(s.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(_r)}function _r(t,e){return t.faceId<e.faceId?-1:t.faceId>e.faceId?1:t.arc_length<e.arc_length?-1:t.arc_length>e.arc_length?1:0}function Cr(t){if(t.int_points1.length<2)return;let e,n,s,o,i=!1;for(let r=0;r<t.int_points1_sorted.length;r++)if(-1!==t.int_points1_sorted[r].id){e=t.int_points1_sorted[r],n=t.int_points2[e.id];for(let a=r+1;a<t.int_points1_sorted.length&&(s=t.int_points1_sorted[a],Di(s.arc_length,e.arc_length));a++)-1!==s.id&&(o=t.int_points2[s.id],-1!==o.id&&s.edge_before===e.edge_before&&s.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(s.id=-1,o.id=-1,i=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let s=1;s<t.int_points2_sorted.length;s++){let o=t.int_points2_sorted[s];if(-1===o.id)continue;if(-1===n.id||!Di(o.arc_length,n.arc_length)){n=o,e=t.int_points1[n.id];continue}let r=t.int_points1[o.id];r.edge_before===e.edge_before&&r.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(r.id=-1,o.id=-1,i=!0)}i&&(t.int_points1=t.int_points1.filter(t=>t.id>=0),t.int_points2=t.int_points2.filter(t=>t.id>=0),t.int_points1.forEach((t,e)=>t.id=e),t.int_points2.forEach((t,e)=>t.id=e))}function Tr(t){for(let e of t)e.edge_before&&(e.edge_before.bvStart=void 0,e.edge_before.bvEnd=void 0,e.edge_before.bv=void 0,e.edge_before.overlap=void 0),e.edge_after&&(e.edge_after.bvStart=void 0,e.edge_after.bvEnd=void 0,e.edge_after.bv=void 0,e.edge_after.overlap=void 0);for(let e of t)e.edge_before&&(e.edge_before.bvEnd=2),e.edge_after&&(e.edge_after.bvStart=2)}function Er(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function wr(t,e,n){let s,o,i=1;if(1===t.length)return 1;s=t[e];for(let r=e+1;r<t.length&&s.face===n&&(o=t[r],o.pt.equalTo(s.pt)&&o.edge_before===s.edge_before&&o.edge_after===s.edge_after);r++)i++;return i}function Rr(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start&&e.shape.start.equalTo(n.pt)&&(n.is_vertex|=1),e.shape.end&&e.shape.end.equalTo(n.pt)&&(n.is_vertex|=2),1&n.is_vertex){n.edge_before=e.prev,e.prev&&(n.is_vertex=2);continue}if(2&n.is_vertex)continue;let s=t.addVertex(n.pt,e);n.edge_before=s}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof Sr&&1&n.is_vertex&&(n.edge_after=t.first)}}function Or(t,e,n){const s=t.edge_before,o=e.edge_after,i=n.length;s.next=n[0],n[0].prev=s,n[i-1].next=o,o.prev=n[i-1]}Xi.multiline=(...t)=>new Xi.Multiline(...t);var{INSIDE:Ar,OUTSIDE:zr,BOUNDARY:Lr,OVERLAP_SAME:Dr,OVERLAP_OPPOSITE:Fr}=Ri,{NOT_VERTEX:Yr,START_VERTEX:Xr,END_VERTEX:kr}=Ri;function $r(t,e){let n=e.clone().reverse(),[s,o]=Vr(t,n,3,!0);return s}function Br(t,e){let[n,s]=Vr(t,e,2,!0);return n}function jr(t,e){let[n,s]=Vr(t,e,2,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];let i=[];for(let t of s.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return[o,i]}function Wr(t,e){let[n,s]=Vr(t,e,3,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];return o}function Hr(t,e){let n=t.clone(),s=e.clone(),o=Gr(n,s);return Nr(o),Rr(n,o.int_points1_sorted),Rr(s,o.int_points2_sorted),Cr(o),Nr(o),[o.int_points1_sorted.map(t=>t.pt),o.int_points2_sorted.map(t=>t.pt)]}function Ur(t,e,n,s){let o=Zr(t,n.int_points1),i=Zr(e,n.int_points2);for(qr(o,e),qr(i,t),Tr(n.int_points1),Tr(n.int_points2),Er(n.int_points1,e),Er(n.int_points2,t);Jr(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,s,o=t.int_points1.length;for(let i=0;i<o;i++){let r=t.int_points1_sorted[i];r.face!==e&&(n=i,e=r.face);let a,c=i,h=wr(t.int_points1_sorted,i,e);a=c+h<o&&t.int_points1_sorted[c+h].face===e?c+h:n;let l=wr(t.int_points1_sorted,a,e);s=null;for(let n=a;n<a+l;n++){let o=t.int_points1_sorted[n];if(o.face===e&&t.int_points2[o.id].face===t.int_points2[r.id].face){s=o;break}}if(null===s)continue;let d=r.edge_after,u=s.edge_before;if(2!==d.bv||2!==u.bv)continue;if(d!==u)continue;let p=t.int_points2[r.id],f=t.int_points2[s.id],m=p.edge_after,g=f.edge_before;2===m.bv&&2===g.bv&&m===g||(p=t.int_points2[s.id],f=t.int_points2[r.id],m=p.edge_after,g=f.edge_before),2===m.bv&&2===g.bv&&m===g&&d.setOverlap(m)}}(n),Kr(t,s,n.int_points1_sorted,!0),Kr(e,s,n.int_points2_sorted,!1),ea(t,o,s,!0),ea(e,i,s,!1)}function Vr(t,e,n,s){let o=t.clone(),i=e.clone(),r=Gr(o,i);return Nr(r),Rr(o,r.int_points1_sorted),Rr(i,r.int_points2_sorted),Cr(r),Nr(r),Ur(o,i,r,n),s&&function(t,e,n){!function(t,e,n,s){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===s.find(t=>t.face===n)&&t.addFace(n.first,n.last)}}(t,e,0,n.int_points2),function(t,e,n){if(0!==n.int_points1.length)for(let t=0;t<n.int_points1.length;t++){let e=n.int_points1[t],s=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===s.edge_before&&void 0!==s.edge_after&&(e.edge_before.next=s.edge_after,s.edge_after.prev=e.edge_before,e.edge_after=s.edge_after,s.edge_before=e.edge_before),void 0!==s.edge_before&&void 0===s.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(s.edge_before.next=e.edge_after,e.edge_after.prev=s.edge_before,s.edge_after=e.edge_after,e.edge_before=s.edge_before),void 0!==e.edge_before&&void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(e.pt)&&(e.edge_before.next=t.edge_after,t.edge_after.prev=e.edge_before,e.edge_after=t.edge_after,t.edge_before=e.edge_before);if(void 0!==s.edge_before&&void 0===s.edge_after)for(let t of n.int_points2_sorted)t!==s&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(s.pt)&&(s.edge_before.next=t.edge_after,t.edge_after.prev=s.edge_before,s.edge_after=t.edge_after,t.edge_before=s.edge_before)}}(0,0,n),Qr(t,n.int_points1),Qr(e,n.int_points2),ta(t,n.int_points1,n.int_points2),ta(t,n.int_points2,n.int_points1)}(o,i,r),[o,i]}function Gr(t,e){let n={int_points1:[],int_points2:[]};for(let s of t.edges){let t=e.edges.search(s.box);for(let e of t){let t=s.shape.intersect(e.shape);for(let o of t)Mr(s,o,n.int_points1),Mr(e,o,n.int_points2)}}return n}function Zr(t,e){let n=[];for(let s of t.faces)e.find(t=>t.face===s)||n.push(s);return n}function qr(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function Jr(t,e,n,s,o,i){let r,a,c,h=s.length,l=!1;for(let d=0;d<h;d++){let u=s[d];u.face!==r&&(a=d,r=u.face);let p,f=d,m=wr(s,d,r);p=f+m<h&&s[f+m].face===r?f+m:a;let g=wr(s,p,r);c=null;for(let t=p;t<p+g;t++){let e=s[t];if(e.face===r&&o[e.id].face===o[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,x=c.edge_before;if(y.bv!==Lr||x.bv==Lr)if(y.bv==Lr||x.bv!==Lr){if(y.bv===Lr&&x.bv===Lr&&y!=x||y.bv===Ar&&x.bv===zr||y.bv===zr&&x.bv===Ar){let t=y.next;for(;t!=x;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===Lr&&x.bv===Lr&&y!=x){let t,e=y.next;for(;e!=x;){if(e.bv!=Lr)if(void 0===t)t=e.bv;else if(e.bv!=t)throw ki.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,x.bv=t);continue}if(y.bv===Ar&&x.bv===zr||y.bv===zr&&x.bv===Ar){let s=y;for(;s!=x;){if(s.bvStart===y.bv&&s.bvEnd===x.bv){let[r,a]=s.shape.distanceTo(e);if(r<10*Xi.DP_TOL){Mr(s,a.ps,n);let r=n[n.length-1];if(r.is_vertex&Xr)r.edge_after=s,r.edge_before=s.prev,s.bvStart=Lr,s.bv=void 0,s.setInclusion(e);else if(r.is_vertex&kr)r.edge_after=s.next,s.bvEnd=Lr,s.bv=void 0,s.setInclusion(e);else{let t=e.addVertex(r.pt,s);r.edge_before=t,r.edge_after=t.next,t.setInclusion(e),t.next.bvStart=Lr,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);Mr(c,a.pe,o);let h=o[o.length-1];if(h.is_vertex&Xr)h.edge_after=c,h.edge_before=c.prev;else if(h.is_vertex&kr)h.edge_after=c.next;else{let n=o.find(t=>t.edge_after===c),s=e.addVertex(h.pt,c);h.edge_before=s,h.edge_after=s.next,n&&(n.edge_after=s),s.bvStart=void 0,s.bvEnd=Lr,s.bv=void 0,s.setInclusion(t),s.next.bvStart=Lr,s.next.bvEnd=void 0,s.next.bv=void 0,s.next.setInclusion(t)}Nr(i),l=!0;break}}s=s.next}if(l)break;throw ki.UNRESOLVED_BOUNDARY_CONFLICT}}else x.bv=y.bv;else y.bv=x.bv}return l}function Kr(t,e,n,s){if(!n)return;let o,i,r,a;for(let c=0;c<n.length;c++){if(r=n[c],r.face!==o&&(i=c,o=r.face),o.isEmpty())continue;let h,l=c,d=wr(n,c,o);h=l+d<n.length&&n[l+d].face===r.face?l+d:i,a=n[h];let u=h,p=wr(n,u,o),f=r.edge_after,m=a.edge_before;if(f.bv===Ar&&m.bv===Ar&&1===e||f.bv===zr&&m.bv===zr&&2===e||(f.bv===zr||m.bv===zr)&&3===e&&!s||(f.bv===Ar||m.bv===Ar)&&3===e&&s||f.bv===Lr&&m.bv===Lr&&f.overlap&Dr&&s||f.bv===Lr&&m.bv===Lr&&f.overlap&Fr){t.removeChain(o,f,m);for(let t=l;t<l+d;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=d-1}}function Qr(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before&&(n.edge_before.face=void 0),n.edge_after&&(n.edge_after.face=void 0)}function ta(t,e,n){for(let s of e){if(void 0===s.edge_before||void 0===s.edge_after)continue;if(s.face)continue;if(s.edge_after.face||s.edge_before.face)continue;let o=s.edge_after,i=s.edge_before;try{$i.testInfiniteLoop(o)}catch(t){throw ki.CANNOT_COMPLETE_BOOLEAN_OPERATION}let r=t.addFace(o,i);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r)}}function ea(t,e,n,s){for(let o of e){let e=o.first.bv;(1===n&&e===Ar||3===n&&e===Ar&&s||3===n&&e===zr&&!s||2===n&&e===zr)&&t.deleteFace(o)}}var na=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:Hr,innerClip:jr,intersect:Br,outerClip:Wr,removeNotRelevantChains:Kr,removeOldFaces:Qr,restoreFaces:ta,subtract:$r,unify:function(t,e){let[n,s]=Vr(t,e,1,!0);return n}}),sa=RegExp("T.F..FFF.|T.F...F.."),oa=RegExp("T........|.T.......|...T.....|....T...."),ia=RegExp("FT.......|F..T.....|F...T...."),ra=RegExp("T.F..F..."),aa=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),ca=class{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&0===t.length?"F":"*").join("")}equal(){return sa.test(this.toString())}intersect(){return oa.test(this.toString())}touch(){return ia.test(this.toString())}inside(){return ra.test(this.toString())}covered(){return aa.test(this.toString())}};function ha(t,e){let n,s=new Xi.Ray(e),o=new Xi.Line(s.pt,s.norm);const i=new Xi.Box(s.box.xmin-Xi.DP_TOL,s.box.ymin-Xi.DP_TOL,s.box.xmax+Xi.DP_TOL,s.box.ymax+Xi.DP_TOL);if(t.box.not_intersect(i))return Xi.OUTSIDE;let r=t.edges.search(i);if(0===r.length)return Xi.OUTSIDE;for(let t of r)if(t.shape.contains(e))return Xi.BOUNDARY;let a=[...t.faces],c=[];for(let t of r)for(let n of s.intersect(t.shape)){if(n.equalTo(e))return Xi.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>Yi(t.pt.x,e.pt.x)?-1:Fi(t.pt.x,e.pt.x)?1:t.face_index<e.face_index?-1:t.face_index>e.face_index?1:t.edge.arc_length<e.edge.arc_length?-1:t.edge.arc_length>e.edge.arc_length?1:0);let h=0;for(let t=0;t<c.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;Li(n.length);)n=n.prev;let s=n.shape.tangentInEnd(),i=e.pt.translate(s),r=e.edge.shape.tangentInStart(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.pt.equalTo(e.edge.shape.end)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;Li(n.length);)n=n.next;let s=n.shape.tangentInStart(),i=e.pt.translate(s),r=e.edge.shape.tangentInEnd(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.edge.shape instanceof Xi.Segment)h++;else{let t=e.edge.shape.box;Di(e.pt.y,t.ymin)||Di(e.pt.y,t.ymax)||h++}}return n=h%2==1?1:0,n}function la(t,e){return fa(t,e).intersect()}function da(t,e){return fa(t,e).inside()}function ua(t,e){return fa(t,e).covered()}function pa(t,e){return ua(e,t)}function fa(t,e){return t instanceof Xi.Line&&e instanceof Xi.Line?function(t,e){let n=new ca,s=Hi(t,e);0===s.length?t.contains(e.pt)&&e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=s,n.I2E=t.split(s),n.E2I=e.split(s));return n}(t,e):t instanceof Xi.Line&&e instanceof Xi.Circle?function(t,e){let n=new ca,s=Ui(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Sr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new Xi.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof Xi.Line&&e instanceof Xi.Box?function(t,e){let n=new ca,s=Vi(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Sr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();e.toSegments().some(t=>t.contains(s[0])&&t.contains(s[1]))?(n.I2I=[],n.I2B=[r[1]],n.I2E=[r[0],r[2]],n.E2I=[e]):(n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new Xi.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof Xi.Line&&e instanceof Xi.Polygon?function(t,e){let n=new ca,s=hr(t,e),o=new Sr([t]),i=s.length>0?s.slice():t.sortPoints(s);return o.split(i),[...o].forEach(t=>t.setInclusion(e)),n.I2I=[...o].filter(t=>t.bv===Xi.INSIDE).map(t=>t.shape),n.I2B=[...o].slice(1).map(t=>t.bv===Xi.BOUNDARY?t.shape:t.shape.start),n.I2E=[...o].filter(t=>t.bv===Xi.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof Xi.Segment||t instanceof Xi.Arc)&&e instanceof Xi.Polygon?ma(t,e):(t instanceof Xi.Segment||t instanceof Xi.Arc)&&(e instanceof Xi.Circle||e instanceof Xi.Box)?ma(t,new Xi.Polygon(e)):t instanceof Xi.Polygon&&e instanceof Xi.Polygon?ga(t,e):(t instanceof Xi.Circle||t instanceof Xi.Box)&&(e instanceof Xi.Circle||e instanceof Xi.Box)?ga(new Xi.Polygon(t),new Xi.Polygon(e)):(t instanceof Xi.Circle||t instanceof Xi.Box)&&e instanceof Xi.Polygon?ga(new Xi.Polygon(t),e):t instanceof Xi.Polygon&&(e instanceof Xi.Circle||e instanceof Xi.Box)?ga(t,new Xi.Polygon(e)):void 0}function ma(t,e){let n=new ca,s=function(t,e){return t instanceof Xi.Line?hr(t,e):t instanceof Xi.Segment?ar(t,e):t instanceof Xi.Arc?cr(t,e):[]}(t,e),o=s.length>0?s.slice():t.sortPoints(s),i=new Sr([t]);i.split(o),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===Xi.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===Xi.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===Xi.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let s of[t.start,t.end])switch(ha(e,s)){case Xi.INSIDE:n.B2I.push(s);break;case Xi.BOUNDARY:n.B2B.push(s);break;case Xi.OUTSIDE:n.B2E.push(s)}return n}function ga(t,e){let n=new ca,[s,o]=Hr(t,e),i=Br(t,e),r=$r(t,e),a=$r(e,t),[c,h]=jr(t,e),l=Wr(t,e),d=Wr(e,t);return n.I2I=i.isEmpty()?[]:[i],n.I2B=h,n.I2E=r.isEmpty()?[]:[r],n.B2I=c,n.B2B=s,n.B2E=l,n.E2I=a.isEmpty()?[]:[a],n.E2B=d,n}var ya=Object.freeze({__proto__:null,contain:function(t,e){return da(e,t)},cover:pa,covered:ua,disjoint:function(t,e){return!la(t,e)},equal:function(t,e){return fa(t,e).equal()},inside:da,intersect:la,relate:fa,touch:function(t,e){return fa(t,e).touch()}}),xa=class t{constructor(t=1,e=0,n=0,s=1,o=0,i=0){this.a=t,this.b=e,this.c=n,this.d=s,this.tx=o,this.ty=i}fromMatrix3x3(e){const[n,s,o]=e[0],[i,r,a]=e[1];return new t(n,i,s,r,o,a)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new t(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(e){return new t(this.a*e.a+this.c*e.b,this.b*e.a+this.d*e.b,this.a*e.c+this.c*e.d,this.b*e.c+this.d*e.d,this.a*e.tx+this.c*e.ty+this.tx,this.b*e.tx+this.d*e.ty+this.ty)}translate(...e){let n,s;if(1!=e.length||isNaN(e[0].x)||isNaN(e[0].y)){if(2!==e.length||"number"!=typeof e[0]||"number"!=typeof e[1])throw ki.ILLEGAL_PARAMETERS;n=e[0],s=e[1]}else n=e[0].x,s=e[0].y;return this.multiply(new t(1,0,0,1,n,s))}rotate(e,n=0,s=0){let o=Math.cos(e),i=Math.sin(e);return this.translate(n,s).multiply(new t(o,i,-i,o,0,0)).translate(-n,-s)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!Xi.Utils.EQ(this.tx,t.tx)&&(!!Xi.Utils.EQ(this.ty,t.ty)&&(!!Xi.Utils.EQ(this.a,t.a)&&(!!Xi.Utils.EQ(this.b,t.b)&&(!!Xi.Utils.EQ(this.c,t.c)&&!!Xi.Utils.EQ(this.d,t.d)))))}};Xi.Matrix=xa;Xi.matrix=(...t)=>new Xi.Matrix(...t);var va=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const e=void 0===this.low?t.low:this.low<t.low?this.low:t.low,n=void 0===this.high?t.high:this.high>t.high?this.high:t.high,s=this.clone();return s.low=e,s.high=n,s}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},ba=class t extends va{clone(){return new t(this.low,this.high)}},Pa=class{constructor(t,e,n=null,s=null,o=null,i=0){if(this.left=n,this.right=s,this.parent=o,this.color=i,this.item={key:void 0,values:[]},void 0!==e&&this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)&&!Number.isNaN(n)){let t=e,s=n;t>s&&([t,s]=[s,t]),this.item.key=new ba(t,s)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key&&0===this.item.values.length&&null===this.left&&null===this.right&&0===this.color}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const e=this.requireKey(),n=t.requireKey();return e.less_than(n)}_value_equal(t){const e=this.item.values[0],n=t.item.values[0];return e&&n&&e.equal_to?e.equal_to(n):e===n}equal_to(t){const e=this.requireKey(),n=t.requireKey();return e.equal_to(n)}intersect(t){const e=this.requireKey(),n=t.requireKey();return e.intersect(n)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const e=this.left.max?this.left.max.high:this.left.item.key.high,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(e,s.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const e=this.right.max?this.right.max.low:this.right.item.key.low,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(s.high,e)}},Sa=class t{constructor(){this.root=null,this.nil_node=new Pa}get size(){let t=0;return this.tree_walk(this.root,e=>t+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=>{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=>{const n=e.item.key.output();for(const s of e.item.values)t.push({key:n,value:s})}),t}isEmpty(){return null==this.root||this.root===this.nil_node}clear(){this.root=null}insert(t,e=t){if(void 0===t)return;const n=this.tree_search(this.root,new Pa(t));if(n)return n.item.values.push(e),n;const s=new Pa(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(s),this.recalc_max(s),s}exist(t,e=t){const n=this.tree_search(this.root,new Pa(t));return!!n&&(arguments.length<2||e===t||n.item.values.some(t=>t&&t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new Pa(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const s=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return s>=0?(n.item.values.splice(s,1),0===n.item.values.length&&this.tree_delete(n),n):void 0}search(t,e=(t,e)=>t===e?e.output():t){const n=new Pa(t),s=[];this.tree_search_interval(this.root,n,s);const o=[];for(const t of s)for(const n of t.item.values)o.push(e(n,t.item.key));return o}intersect_any(t){const e=new Pa(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>{for(const n of e.item.values)t(e.item.key,n)})}map(e){const n=new t;return this.tree_walk(this.root,t=>{for(const s of t.item.values)n.insert(t.item.key,e(s,t.item.key))}),n}*iterate(t,e=(t,e)=>t===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new Pa(t)):this.root&&(n=this.local_minimum(this.root));n;){for(const t of n.item.values)yield e(t,n.item.key);n=this.tree_successor(n)}}recalc_max(t){let e=t;for(;null!=e.parent;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(null==this.root||this.root===this.nil_node)this.root=t;else{for(;e!==this.nil_node;)n=e,e=t.less_than(e)?e.left:e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!==this.root&&1===e.parent.color;)e.parent===e.parent.parent.left?(n=e.parent.parent.right,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_left(e.parent.parent)));this.root.color=0}tree_delete(t){let e,n;e=t.left===this.nil_node||t.right===this.nil_node?t:this.tree_successor(t),n=e.left!==this.nil_node?e.left:e.right,n.parent=e.parent,e===this.root?this.root=n:(e===e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!==t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color&&this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root&&null!=n.parent&&0===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.right.color&&(e.color=1,e.left.color=0,this.rotate_right(e),e=n.parent.right),e.color=n.parent.color,n.parent.color=0,e.right.color=0,this.rotate_left(n.parent),n=this.root)):(e=n.parent.left,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.left.color&&(e.color=1,e.right.color=0,this.rotate_left(e),e=n.parent.left),e.color=n.parent.color,n.parent.color=0,e.left.color=0,this.rotate_right(n.parent),n=this.root));n.color=0}tree_search(t,e){if(null!=t&&t!==this.nil_node)return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_nearest_forward(t,e){let n=null,s=t;for(;s&&s!==this.nil_node;)s.less_than(e)?s.intersect(e)?(n=s,s=s.left):s=s.right:(n&&!s.less_than(n)||(n=s),s=s.left);return n||null}tree_search_interval(t,e,n){null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right===this.nil_node||t.not_intersect_right_subtree(e)||this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),n||t.right===this.nil_node||t.not_intersect_right_subtree(e)||(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;null!=e.left&&e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right&&e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,s;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,s=t.parent;null!=s&&s.right===n;)n=s,s=s.parent;e=s}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node&&(e.left.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node&&(e.right.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}tree_walk(t,e){null!=t&&t!==this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){1===e.color&&(0===e.left.color&&0===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,s=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,s=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==s)throw new Error("Red-black height property violated");return e+=n,e}},Ma=class extends Set{constructor(t){super(t),this.index=new Sa,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:s}=t,o=n||t.box,i=s||t;return super.add(i),this.size>e&&this.index.insert(o,i),this}delete(t){const{key:e,value:n}=t,s=e||t.box,o=n||t;let i=super.delete(o);return i&&this.index.remove(s,o),i}clear(){super.clear(),this.index=new Sa}search(t){return this.index.search(t)}hit(t){let e=new Xi.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=>t.on(e))}svg(){return[...this].reduce((t,e)=>t+e.svg(),"")}};Xi.PlanarSet=Ma;var Na=class{get name(){throw ki.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw ki.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw ki.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new xa).translate(...t))}rotate(t,e=new Xi.Point){return this.transform((new xa).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new xa).scale(t,e))}transform(...t){throw ki.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw ki.CANNOT_INVOKE_ABSTRACT_METHOD}};Xi.Point=class t extends Na{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"point"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw ki.ILLEGAL_PARAMETERS}}get box(){return new Xi.Box(this.x,this.y,this.x,this.y)}clone(){return new Xi.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return Xi.Utils.EQ(this.x,t.x)&&Xi.Utils.EQ(this.y,t.y)}lessThan(t){return!!Xi.Utils.LT(this.y,t.y)||!(!Xi.Utils.EQ(this.y,t.y)||!Xi.Utils.LT(this.x,t.x))}transform(t){return new Xi.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new Xi.Vector(this,t.pt);if(Xi.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),s=t.norm.multiply(n);return this.translate(s)}leftTo(t){let e=new Xi.Vector(t.pt,this);return Xi.Utils.GT(e.dot(t.norm),0)}distanceTo(e){if(e instanceof t){let t=e.x-this.x,n=e.y-this.y;return[Math.sqrt(t*t+n*n),new Xi.Segment(this,e)]}return e instanceof Xi.Line?Xi.Distance.point2line(this,e):e instanceof Xi.Circle?Xi.Distance.point2circle(this,e):e instanceof Xi.Segment?Xi.Distance.point2segment(this,e):e instanceof Xi.Arc?Xi.Distance.point2arc(this,e):e instanceof Xi.Polygon?Xi.Distance.point2polygon(this,e):e instanceof Xi.PlanarSet?Xi.Distance.shape2planarSet(this,e):e instanceof Xi.Multiline?Xi.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof Xi.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw Xi.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const e=t.r??3;return`\n<circle cx="${this.x}" cy="${this.y}" r="${e}"\n ${Wi({fill:"red",...t})} />`}};var Ia=(...t)=>new Xi.Point(...t);Xi.point=Ia;Xi.Vector=class extends Na{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"vector"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{start:e,end:n}=t[0];return this.x=n.x-e.x,void(this.y=n.y-e.y)}if(2===t.length){let e=t[0],n=t[1];if("number"==typeof e&&"number"==typeof n)return this.x=e,void(this.y=n);if(e instanceof Xi.Point&&n instanceof Xi.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw ki.ILLEGAL_PARAMETERS}}clone(){return new Xi.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return Xi.Utils.EQ_0(this.length)}equalTo(t){return Xi.Utils.EQ(this.x,t.x)&&Xi.Utils.EQ(this.y,t.y)}multiply(t){return new Xi.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(this.isZeroLength())throw ki.ZERO_DIVISION;return new Xi.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new Xi.Point){if(0===e.x&&0===e.y)return this.transform((new xa).rotate(t));throw ki.OPERATION_IS_NOT_SUPPORTED}transform(t){return new Xi.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new Xi.Vector(-this.y,this.x)}rotate90CW(){return new Xi.Vector(this.y,-this.x)}invert(){return new Xi.Vector(-this.x,-this.y)}add(t){return new Xi.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new Xi.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),s=Math.atan2(e.cross(n),e.dot(n));return s<0&&(s+=2*Math.PI),s}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var _a=(...t)=>new Xi.Vector(...t);Xi.vector=_a;Xi.Segment=class t extends Na{constructor(...t){if(super(),this.ps=new Xi.Point,this.pe=new Xi.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new Xi.Point(e[0],e[1]),void(this.pe=new Xi.Point(e[2],e[3]))}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new Xi.Point(e.x,e.y),void(this.pe=new Xi.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof Xi.Point)){if(2===t.length&&t[0]instanceof Xi.Point&&t[1]instanceof Xi.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new Xi.Point(t[0],t[1]),void(this.pe=new Xi.Point(t[2],t[3]));throw ki.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new Xi.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new Xi.Vector(this.start,this.end).slope}get box(){return new Xi.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return Xi.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Line?Zi(this,t):t instanceof Xi.Ray?mr(t,this):t instanceof Xi.Segment?qi(this,t):t instanceof Xi.Circle?Ki(this,t):t instanceof Xi.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=qi(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Xi.Arc?Qi(this,t):t instanceof Xi.Polygon?ar(this,t):t instanceof Xi.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Xi.Point){let[e,n]=Xi.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Circle){let[e,n]=Xi.Distance.segment2circle(this,t);return[e,n]}if(t instanceof Xi.Line){let[e,n]=Xi.Distance.segment2line(this,t);return[e,n]}if(t instanceof Xi.Segment){let[e,n]=Xi.Distance.segment2segment(this,t);return[e,n]}if(t instanceof Xi.Arc){let[e,n]=Xi.Distance.segment2arc(this,t);return[e,n]}if(t instanceof Xi.Polygon){let[e,n]=Xi.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Xi.PlanarSet){let[e,n]=Xi.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Xi.Multiline)return Xi.Distance.shape2multiline(this,t)}tangentInStart(){return new Xi.Vector(this.start,this.end).normalize()}tangentInEnd(){return new Xi.Vector(this.end,this.start).normalize()}reverse(){return new t(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new Xi.Segment(this.start,t),new Xi.Segment(t,this.end)]}middle(){return new Xi.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new Xi.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=Xi.Distance.point2segment(t,this);return e}definiteIntegral(t=0){return(this.end.x-this.start.x)*(this.start.y-t+(this.end.y-t))/2}transform(e=new Xi.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new Xi.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return`\n<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${Wi(t)} />`}};var Ca=(...t)=>new Xi.Segment(...t);Xi.segment=Ca;var{vector:Ta}=Xi;Xi.Line=class t extends Na{constructor(...e){if(super(),this.pt=new Xi.Point,this.norm=new Xi.Vector(0,1),0!==e.length){if(1===e.length&&e[0]instanceof Object&&"line"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new Xi.Point(t),void(this.norm=new Xi.Vector(n))}if(2===e.length){let n=e[0],s=e[1];if(n instanceof Xi.Point&&s instanceof Xi.Point)return this.pt=n,this.norm=t.points2norm(n,s),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof Xi.Point&&s instanceof Xi.Vector){if(Xi.Utils.EQ_0(s.x)&&Xi.Utils.EQ_0(s.y))throw ki.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=s.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof Xi.Vector&&s instanceof Xi.Point){if(Xi.Utils.EQ_0(n.x)&&Xi.Utils.EQ_0(n.y))throw ki.ILLEGAL_PARAMETERS;return this.pt=s.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw ki.ILLEGAL_PARAMETERS}}clone(){return new Xi.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new Xi.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new Xi.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(Ta(this.pt.x,this.pt.y))]}parallelTo(t){return Xi.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new Xi.Vector(this.pt,t);return Xi.Utils.EQ_0(this.norm.dot(e))}coord(t){return Ta(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Line?Hi(this,t):t instanceof Xi.Ray?xr(t,this):t instanceof Xi.Circle?Ui(this,t):t instanceof Xi.Box?Vi(this,t):t instanceof Xi.Segment?Zi(t,this):t instanceof Xi.Arc?Gi(this,t):t instanceof Xi.Polygon?hr(this,t):t instanceof Xi.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Xi.Point){let[e,n]=Xi.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Circle){let[e,n]=Xi.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Segment){let[e,n]=Xi.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof Xi.Arc){let[e,n]=Xi.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof Xi.Polygon){let[e,n]=Xi.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof Xi.Point)return[new Xi.Ray(t,this.norm),new Xi.Ray(t,this.norm)];{let e=new Xi.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new Xi.Point){return new Xi.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new Xi.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=>this.coord(t)<this.coord(e)?-1:this.coord(t)>this.coord(e)?1:0)}get name(){return"line"}svg(t,e={}){let n=Vi(this,t);if(0===n.length)return"";let s=n[0],o=2===n.length?n[1]:n.find(t=>!t.equalTo(s));return void 0===o&&(o=s),new Xi.Segment(s,o).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw ki.ILLEGAL_PARAMETERS;return new Xi.Vector(t,e).normalize().rotate90CCW()}};var Ea=(...t)=>new Xi.Line(...t);Xi.line=Ea;Xi.Circle=class extends Na{constructor(...t){if(super(),this.pc=new Xi.Point,this.r=1,1===t.length&&t[0]instanceof Object&&"circle"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new Xi.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof Xi.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new Xi.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new Xi.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){return t instanceof Xi.Point?Xi.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof Xi.Segment?Xi.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&Xi.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof Xi.Arc?0===this.intersect(t).length&&Xi.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&Xi.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof Xi.Circle?0===this.intersect(t).length&&Xi.Utils.LE(t.r,this.r)&&Xi.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new Xi.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw ki.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw ki.OPERATION_IS_NOT_SUPPORTED;return new Xi.Circle(this.pc,this.r*t)}transform(t=new Xi.Matrix){return new Xi.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Line?Ui(t,this):t instanceof Xi.Ray?yr(t,this):t instanceof Xi.Segment?Ki(t,this):t instanceof Xi.Circle?tr(t,this):t instanceof Xi.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=Ki(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Xi.Arc?nr(t,this):t instanceof Xi.Polygon?lr(this,t):t instanceof Xi.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Xi.Point){let[e,n]=Xi.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Circle){let[e,n]=Xi.Distance.circle2circle(this,t);return[e,n]}if(t instanceof Xi.Line){let[e,n]=Xi.Distance.circle2line(this,t);return[e,n]}if(t instanceof Xi.Segment){let[e,n]=Xi.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Arc){let[e,n]=Xi.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Polygon){let[e,n]=Xi.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Xi.PlanarSet){let[e,n]=Xi.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Xi.Multiline){let[e,n]=Xi.Distance.shape2multiline(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return`\n<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"\n ${Wi({fill:"none",...t})} />`}};Xi.circle=(...t)=>new Xi.Circle(...t);Xi.Arc=class extends Na{constructor(...t){if(super(),this.pc=new Xi.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length&&t[0]instanceof Object&&"arc"===t[0].name){let{pc:e,r:n,startAngle:s,endAngle:o,counterClockwise:i}=t[0];this.pc=new Xi.Point(e.x,e.y),this.r=n,this.startAngle=s,this.endAngle=o,this.counterClockwise=i}else{let[e,n,s,o,i]=[...t];e&&e instanceof Xi.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==s&&(this.startAngle=s),void 0!==o&&(this.endAngle=o),void 0!==i&&(this.counterClockwise=i)}}clone(){return new Xi.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(Xi.Utils.EQ(Math.abs(t-e),Xi.PIx2))return Xi.PIx2;Math.abs(t)>Xi.PIx2&&(t-=Math.trunc(t/Xi.PIx2)*Xi.PIx2),t<0&&(t+=Xi.PIx2),Math.abs(e)>Xi.PIx2&&(e-=Math.trunc(e/Xi.PIx2)*Xi.PIx2),e<0&&(e+=Xi.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=Xi.PIx2),n}get start(){return new Xi.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new Xi.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let t=this.breakToFunctional().reduce((t,e)=>t.merge(e.start.box),new Xi.Box);return t=t.merge(this.end.box),t}contains(t){if(!Xi.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new Xi.Vector(this.pc,t).slope,n=new Xi.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return Xi.Utils.LE(n.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let e=new Xi.Vector(this.pc,t).slope;return[new Xi.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new Xi.Arc(this.pc,this.r,e,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new Xi.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(0===t)return this.start;if(t===this.length)return this.end;let e=t/this.length,n=this.counterClockwise?this.startAngle+this.sweep*e:this.startAngle-this.sweep*e;return new Xi.Arc(this.pc,this.r,this.startAngle,n,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Line?Gi(t,this):t instanceof Xi.Ray?gr(t,this):t instanceof Xi.Circle?nr(this,t):t instanceof Xi.Segment?Qi(t,this):t instanceof Xi.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=Qi(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Xi.Arc?er(this,t):t instanceof Xi.Polygon?cr(this,t):t instanceof Xi.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Xi.Point){let[e,n]=Xi.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Circle){let[e,n]=Xi.Distance.arc2circle(this,t);return[e,n]}if(t instanceof Xi.Line){let[e,n]=Xi.Distance.arc2line(this,t);return[e,n]}if(t instanceof Xi.Segment){let[e,n]=Xi.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Arc){let[e,n]=Xi.Distance.arc2arc(this,t);return[e,n]}if(t instanceof Xi.Polygon){let[e,n]=Xi.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Xi.PlanarSet){let[e,n]=Xi.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Xi.Multiline)return Xi.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,s=this.endAngle;Xi.Utils.EQ(Math.abs(n-s),Xi.PIx2)&&(s=n),Math.abs(n)>Xi.PIx2&&(n-=Math.trunc(n/Xi.PIx2)*Xi.PIx2),n<0&&(n+=Xi.PIx2),Math.abs(s)>Xi.PIx2&&(s-=Math.trunc(s/Xi.PIx2)*Xi.PIx2),s<0&&(s+=Xi.PIx2);let o,i,r,a=n;this.counterClockwise?(i=Math.ceil(n/(Math.PI/2))%4,r=1):(i=Math.floor(n/(Math.PI/2))%4,r=-1);for(let s=0,c=i;s<4;s++,c=(c+r+4)%4){if(o=e[c],o===a)continue;let s=this.counterClockwise?o-n:n-o;if(s<0&&(s+=Xi.PIx2),s>this.sweep)break;t.push(new Xi.Arc(this.pc,this.r,a,o,this.counterClockwise)),a=o}return 0===t.length?(t.push(this),t):(o=s,a!==o&&t.push(new Xi.Arc(this.pc,this.r,a,o,this.counterClockwise)),t)}tangentInStart(){let t=new Xi.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new Xi.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new Xi.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new Xi.Matrix){let e=this.start.transform(t),n=this.end.transform(t),s=this.pc.transform(t),o=this.counterClockwise;return t.a*t.d<0&&(o=!o),Xi.Arc.arcSE(s,e,n,o)}static arcSE(t,e,n,s){let{vector:o}=Xi,i=o(t,e).slope,r=o(t,n).slope;Xi.Utils.EQ(i,r)&&(r+=2*Math.PI,s=!0);let a=o(t,e).length;return new Xi.Arc(t,a,i,r,s)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new Xi.Segment(this.start,this.end).definiteIntegral(t),n=Xi.Utils.EQ(this.sweep,Xi.PIx2)?0:this.circularSegmentArea();return this.counterClockwise?e-n:e+n}circularSegmentArea(){return.5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:e}=Xi;return t.slice().sort((t,n)=>{let s=e(this.pc,t).slope,o=e(this.pc,n).slope;return s<o?-1:s>o?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if(Xi.Utils.EQ(this.sweep,2*Math.PI)){return new Xi.Circle(this.pc,this.r).svg(t)}return`\n<path d="M${this.start.x},${this.start.y}\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}"\n ${Wi({fill:"none",...t})} />`}};Xi.arc=(...t)=>new Xi.Arc(...t);Xi.Box=class t extends Na{constructor(t=void 0,e=void 0,n=void 0,s=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new Xi.Point(this.xmin,this.ymin)}get high(){return new Xi.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new Xi.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmax<t.xmin||this.xmin>t.xmax||this.ymax<t.ymin||this.ymin>t.ymax}intersect(t){return!this.not_intersect(t)}merge(e){return new t(void 0===this.xmin?e.xmin:Math.min(this.xmin,e.xmin),void 0===this.ymin?e.ymin:Math.min(this.ymin,e.ymin),void 0===this.xmax?e.xmax:Math.max(this.xmax,e.xmax),void 0===this.ymax?e.ymax:Math.max(this.ymax,e.ymax))}less_than(t){return!!this.low.lessThan(t.low)||!(!this.low.equalTo(t.low)||!this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,s){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new Xi.Point(this.xmin,this.ymin),new Xi.Point(this.xmax,this.ymin),new Xi.Point(this.xmax,this.ymax),new Xi.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new Xi.Segment(t[0],t[1]),new Xi.Segment(t[1],t[2]),new Xi.Segment(t[2],t[3]),new Xi.Segment(t[3],t[0])]}rotate(t,e=new Xi.Point){throw ki.OPERATION_IS_NOT_SUPPORTED}transform(e=new Xi.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof Xi.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof Xi.Segment?t.vertices.every(t=>this.contains(t)):t instanceof Xi.Box?t.toSegments().every(t=>this.contains(t)):t instanceof Xi.Circle?this.contains(t.box):t instanceof Xi.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===Qi(e,t).length):!(t instanceof Xi.Line||t instanceof Xi.Ray)&&(t instanceof Xi.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof Xi.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=>e.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=>{t[0]<n[0]&&(n=t)}),n}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\n<rect x="${this.xmin}" y="${this.ymin}" width="${e}" height="${n}"\n ${Wi({fill:"none",...t})} />`}};Xi.box=(...t)=>new Xi.Box(...t);Xi.Edge=class{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof Xi.Segment}get isArc(){return this.shape instanceof Xi.Arc}get isLine(){return this.shape instanceof Xi.Line}get isRay(){return this.shape instanceof Xi.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(void 0!==this.bv)return this.bv;if(this.shape instanceof Xi.Line||this.shape instanceof Xi.Ray)return this.bv=Xi.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=ha(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=ha(t,this.end)),this.bvStart===Xi.OUTSIDE||this.bvEnd==Xi.OUTSIDE)this.bv=Xi.OUTSIDE;else if(this.bvStart===Xi.INSIDE||this.bvEnd==Xi.INSIDE)this.bv=Xi.INSIDE;else{let e=ha(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,s=t.shape;n instanceof Xi.Segment&&s instanceof Xi.Segment?n.start.equalTo(s.start)&&n.end.equalTo(s.end)?e=Xi.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&(e=Xi.OVERLAP_OPPOSITE):(n instanceof Xi.Arc&&s instanceof Xi.Arc||n instanceof Xi.Segment&&s instanceof Xi.Arc||n instanceof Xi.Arc&&s instanceof Xi.Segment)&&(n.start.equalTo(s.start)&&n.end.equalTo(s.end)&&n.middle().equalTo(s.middle())?e=Xi.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&n.middle().equalTo(s.middle())&&(e=Xi.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof Xi.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof Xi.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if(Xi.Utils.EQ(e.sweep,2*Math.PI)){let s=e.counterClockwise?1:-1,o=new Xi.Arc(e.pc,e.r,e.startAngle,e.startAngle+s*Math.PI,e.counterClockwise),i=new Xi.Arc(e.pc,e.r,e.startAngle+s*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${o.r},${o.r} 0 ${t},${n} ${o.end.x},${o.end.y}\n A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}`}return t=e.sweep<=Math.PI?"0":"1",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var wa=class extends $i{constructor(t,e){super(t,e),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let e=t||this.first,n=!this.first||!!t&&t===this.first;return t=e?e.next:void 0,{value:e,done:n}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,e){return super.insert(t,e),this.setCircularLinks(),this}remove(t){return super.remove(t),this}};Xi.Face=class t extends wa{constructor(e,...n){if(super(),this._box=void 0,this._orientation=void 0,0!==n.length){if(1===n.length)if(n[0]instanceof Array){let s=n[0];if(0===s.length)return;if(s.every(t=>t instanceof Xi.Point)){let n=t.points2segments(s);this.shapes2face(e.edges,n)}else if(s.every(t=>t instanceof Array&&2===t.length)){let n=s.map(t=>new Xi.Point(t[0],t[1])),o=t.points2segments(n);this.shapes2face(e.edges,o)}else if(s.every(t=>t instanceof Xi.Segment||t instanceof Xi.Arc))this.shapes2face(e.edges,s);else if(s.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of s){let n;n="segment"===e.name?new Xi.Segment(e):new Xi.Arc(e),t.push(n)}this.shapes2face(e.edges,t)}}else if(n[0]instanceof t){let t=n[0];this.first=t.first,this.last=t.last;for(let n of t)e.edges.add(n)}else if(n[0]instanceof Xi.Circle)this.shapes2face(e.edges,[n[0].toArc(Ti)]);else if(n[0]instanceof Xi.Box){let t=n[0];this.shapes2face(e.edges,[new Xi.Segment(new Xi.Point(t.xmin,t.ymin),new Xi.Point(t.xmax,t.ymin)),new Xi.Segment(new Xi.Point(t.xmax,t.ymin),new Xi.Point(t.xmax,t.ymax)),new Xi.Segment(new Xi.Point(t.xmax,t.ymax),new Xi.Point(t.xmin,t.ymax)),new Xi.Segment(new Xi.Point(t.xmin,t.ymax),new Xi.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof Xi.Edge&&n[1]instanceof Xi.Edge&&(this.first=n[0],this.last=n[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(void 0===this._box){let t=new Xi.Box;for(let e of this)t=t.merge(e.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n<t.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new Xi.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new Xi.Edge(n);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,e){return super.insert(t,e),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],e=this.last;do{e.shape=e.shape.reverse(),t.push(e),e=e.prev}while(e!==this.last);this.first=void 0,this.last=void 0;for(let e of t)void 0===this.first?(e.prev=e,e.next=e,this.first=e,this.last=e):(e.prev=this.last,this.last.next=e,this.last=e,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(e);void 0!==this._orientation&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,e=this.box.ymin;for(let n of this)t+=n.shape.definiteIntegral(e);return t}orientation(){if(void 0===this._orientation){let t=this.signedArea();Xi.Utils.EQ_0(t)?this._orientation=Ei.NOT_ORIENTABLE:Xi.Utils.LT(t,0)?this._orientation=Ei.CCW:this._orientation=Ei.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let s=[];for(let o of t){let i=e.search(o.box);for(let e of i){if(o===e)continue;if(e.face!==t)continue;if(o.shape instanceof Xi.Segment&&e.shape instanceof Xi.Segment&&(o.next===e||o.prev===e))continue;let i=o.shape.intersect(e.shape);for(let t of i)if((!t.equalTo(o.start)||!t.equalTo(e.end)||e!==o.prev)&&(!t.equalTo(o.end)||!t.equalTo(e.start)||e!==o.next)&&(s.push(t),n))break;if(s.length>0&&n)break}if(s.length>0&&n)break}return s}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)&&(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new Xi.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}};Xi.Ray=class t extends Na{constructor(...t){if(super(),this.pt=new Xi.Point,this.norm=new Xi.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof Xi.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof Xi.Vector))throw ki.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new Xi.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new Xi.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||0===t?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new Xi.Vector(this.pt,t);return Xi.Utils.EQ_0(this.norm.dot(e))&&Xi.Utils.GE(e.cross(this.norm),0)}coord(t){return _a(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new Xi.Segment(this.pt,t),new Xi.Ray(t,this.norm)]:[]}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Segment?mr(this,t):t instanceof Xi.Arc?gr(this,t):t instanceof Xi.Line?xr(this,t):t instanceof Xi.Ray?(n=t,Hi(fr(e=this),fr(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof Xi.Circle?yr(this,t):t instanceof Xi.Box?function(t,e){return Vi(fr(t),e).filter(e=>t.contains(e))}(this,t):t instanceof Xi.Polygon?vr(this,t):t instanceof Xi.Multiline?Pr(this,t):void 0;var e,n}rotate(t,e=new Xi.Point){return new Xi.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new Xi.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=Vi(new Xi.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new Xi.Segment(this.pt,n[0]).svg(e)}};Xi.ray=(...t)=>new Xi.Ray(...t);var Ra=class t{constructor(){this.faces=new Xi.PlanarSet,this.edges=new Xi.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof Xi.Circle||t[0]instanceof Xi.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(t=>t instanceof Array))if(e.every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))this.faces.add(new Xi.Face(this,e));else for(let t of e)if(t instanceof Array&&t[0]instanceof Array&&t[0].every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))for(let e of t)this.faces.add(new Xi.Face(this,e));else this.faces.add(new Xi.Face(this,t));else this.faces.add(new Xi.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new Xi.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let e=new t;for(let t of this.faces)e.addFace(t.shapes);return e}createFromArray(e){const n=new t;return e.forEach(t=>[...t.faces].forEach(t=>n.addFace(t.shapes))),n}isEmpty(){return 0===this.edges.size||0===this.faces.size}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((t,e)=>t+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new Xi.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let t of this.edges)t.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(null===n.face){t=n,e=!0;break}if(e){let e=t;do{e=e.next}while(e.next!==t);this.addFace(t,e)}}}removeChain(t,e,n){if(n.next!==e){for(let s=e;s!==n.next;s=s.next)if(t.remove(s),this.edges.delete(s),t.isEmpty()){this.deleteFace(t);break}}else this.deleteFace(t)}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new Xi.Edge(n[0]),o=e.prev;return e.face.insert(s,o),this.edges.delete(e),this.edges.add(s),e.shape=n[1],this.edges.add(e),s}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(t=>t.isValid()&&!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let s,o,i={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=dr(t,n);for(let s of e)Mr(t,s,i.int_points1),Mr(n,s,i.int_points2)}if(0===i.int_points1.length)return e;i.int_points1_sorted=Ir(i.int_points1),i.int_points2_sorted=Ir(i.int_points2),Rr(n,i.int_points1_sorted),Rr(e,i.int_points2_sorted),Cr(i),i.int_points1_sorted=Ir(i.int_points1),i.int_points2_sorted=Ir(i.int_points2),Tr(i.int_points1),Er(i.int_points1,e);for(let t of i.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(i.int_points2[t.id]=-1,t.id=-1);if(i.int_points1=i.int_points1.filter(t=>t.id>=0),i.int_points2=i.int_points2.filter(t=>t.id>=0),i.int_points1.forEach((t,e)=>{t.id=e}),i.int_points2.forEach((t,e)=>{t.id=e}),0===i.int_points1.length)return e;i.int_points1_sorted=Ir(i.int_points1),i.int_points2_sorted=Ir(i.int_points2);for(let t=1;t<i.int_points1_sorted.length;t++)if(o=i.int_points1_sorted[t],s=i.int_points1_sorted[t-1],o.edge_before&&1===o.edge_before.bv){let t=s.edge_after,r=o.edge_before,a=n.getChain(t,r);Or(i.int_points2[s.id],i.int_points2[o.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new Xi.Edge(t.shape.reverse()));for(let t=0;t<a.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];Or(i.int_points2[o.id],i.int_points2[s.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new Sr([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),void 0!==e)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((t,e)=>e.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=>[...t.faces][0].orientation()===e);for(let s of t){let t=[...s.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=>e.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size<=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=>{t.faces.forEach(t=>n.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?Ei.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=>{this.isOuter(e)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof Xi.Point){let e=ha(this,t);return 1===e||2===e}return pa(this,t)}distanceTo(t){if(t instanceof Xi.Point){let[e,n]=Xi.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Circle||t instanceof Xi.Line||t instanceof Xi.Segment||t instanceof Xi.Arc){let[e,n]=Xi.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof Xi.Polygon){let e,n,s=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let o of this.edges){let i=s[0];[e,n]=Xi.Distance.shape2planarSet(o.shape,t.edges,i),Xi.Utils.LT(e,i)&&(s=[e,n])}return s}}intersect(t){return t instanceof Xi.Point?this.contains(t)?[t]:[]:t instanceof Xi.Line?hr(t,this):t instanceof Xi.Ray?vr(t,this):t instanceof Xi.Circle?lr(t,this):t instanceof Xi.Segment?ar(t,this):t instanceof Xi.Arc?cr(t,this):t instanceof Xi.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let s of t.edges)n=[...n,...ur(s,e)];return n}(t,this):t instanceof Xi.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let s of t)n=[...n,...ur(s,e)];return n}(t,this):void 0}translate(e){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.translate(e)));return n}rotate(e=0,n=new Xi.Point){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.rotate(e,n)));return s}scale(e,n){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.scale(e,n)));return s}transform(e=new Xi.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.transform(e)));return n}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=>t+e.svg(),"")}svg(t={}){let e=`\n<path ${Wi({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};Xi.Polygon=Ra;Xi.polygon=(...t)=>new Xi.Polygon(...t);var{Circle:Oa,Line:Aa,Point:za,Vector:La,Utils:Da}=Xi;Xi.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new La(t.pc,e),s=t.r*t.r,o=n.dot(n);return Da.EQ_0(o)?new za(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(s/o))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(Da.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),s=new La(t.pc,e.pc);s=s.normalize();let o=t.pc.translate(s.multiply(n));return new Aa(o,s)}{let n=new La(t.pc,e.pc),s=t.r*t.r/(n.dot(n)-e.r*e.r),o=t.pc.translate(n.multiply(s)),i=Math.abs(s)*e.r;return new Oa(o,i)}}static inverseLine(t,e){const[n,s]=t.pc.distanceTo(e);if(Da.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),o=new La(t.pc,s.end);return o=o.multiply(e/n),new Oa(t.pc.translate(o),e)}}inverse(e){return e instanceof za?t.inversePoint(this.circle,e):e instanceof Oa?t.inverseCircle(this.circle,e):e instanceof Aa?t.inverseLine(this.circle,e):void 0}};Xi.inversion=t=>new Xi.Inversion(t);Xi.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new Xi.Vector(t,n).length,new Xi.Segment(t,n)]}static point2circle(t,e){let[n,s]=t.distanceTo(e.center);if(Xi.Utils.EQ_0(n))return[e.r,new Xi.Segment(t,e.toArc().start)];{let s=Math.abs(n-e.r),o=new Xi.Vector(e.pc,t).normalize().multiply(e.r),i=e.pc.translate(o);return[s,new Xi.Segment(t,i)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let s,o,i=new Xi.Vector(n.start,n.end),r=new Xi.Vector(n.start,e),a=new Xi.Vector(n.end,e),c=i.dot(r),h=-i.dot(a);if(Xi.Utils.GE(c,0)&&Xi.Utils.GE(h,0)){let t=n.tangentInStart();return s=Math.abs(t.cross(r)),o=n.start.translate(t.multiply(t.dot(r))),[s,new Xi.Segment(e,o)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let s,o,i=new Xi.Circle(n.pc,n.r),r=[];return[s,o]=t.point2circle(e,i),o.end.on(n)&&r.push(t.point2circle(e,i)),r.push(t.point2point(e,n.start)),r.push(t.point2point(e,n.end)),t.sort(r),r[0]}static point2edge(e,n){return n.shape instanceof Xi.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}static segment2segment(e,n){let s=qi(e,n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o,i,r=[];return[o,i]=t.point2segment(n.start,e),r.push([o,i.reverse()]),[o,i]=t.point2segment(n.end,e),r.push([o,i.reverse()]),r.push(t.point2segment(e.start,n)),r.push(t.point2segment(e.end,n)),t.sort(r),r[0]}static segment2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=new Xi.Line(e.ps,e.pe),[i,r]=t.point2line(n.center,o);if(Xi.Utils.GE(i,n.r)&&r.end.on(e))return t.point2circle(r.end,n);{let[s,o]=t.point2circle(e.start,n),[i,r]=t.point2circle(e.end,n);return Xi.Utils.LT(s,i)?[s,o]:[i,r]}}static segment2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=new Xi.Line(e.ps,e.pe),i=new Xi.Circle(n.pc,n.r),[r,a]=t.point2line(i.center,o);if(Xi.Utils.GE(r,i.r)&&a.end.on(e)){let[e,s]=t.point2circle(a.end,i);if(s.end.on(n))return[e,s]}let c,h,l=[];return l.push(t.point2arc(e.start,n)),l.push(t.point2arc(e.end,n)),[c,h]=t.point2segment(n.start,e),l.push([c,h.reverse()]),[c,h]=t.point2segment(n.end,e),l.push([c,h.reverse()]),t.sort(l),l[0]}static circle2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];if(e.center.equalTo(n.center)){let s=e.toArc(),o=n.toArc();return t.point2point(s.start,o.start)}{let s=new Xi.Line(e.center,n.center),o=s.intersect(e),i=s.intersect(n),r=[];return r.push(t.point2point(o[0],i[0])),r.push(t.point2point(o[0],i[1])),r.push(t.point2point(o[1],i[0])),r.push(t.point2point(o[1],i[1])),t.sort(r),r[0]}}static circle2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let[o,i]=t.point2line(e.center,n),[r,a]=t.point2circle(i.end,e);return a=a.reverse(),[r,a]}static arc2line(e,n){let s=n.intersect(e);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=new Xi.Circle(e.center,e.r),[i,r]=t.point2line(o.center,n);if(!Xi.Utils.GE(i,o.r)){let s=[];return s.push(t.point2line(e.start,n)),s.push(t.point2line(e.end,n)),t.sort(s),s[0]}{let[n,s]=t.point2circle(r.end,o);if(s.end.on(e))return[n,s]}}static arc2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=new Xi.Circle(e.center,e.r),[i,r]=t.circle2circle(o,n);if(r.start.on(e))return[i,r];{let s=[];return s.push(t.point2circle(e.start,n)),s.push(t.point2circle(e.end,n)),t.sort(s),s[0]}}static arc2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new Xi.Segment(s[0],s[0])];let o=new Xi.Circle(e.center,e.r),i=new Xi.Circle(n.center,n.r),[r,a]=t.circle2circle(o,i);if(a.start.on(e)&&a.end.on(n))return[r,a];{let s,o,i=[];return[s,o]=t.point2arc(e.start,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(e.end,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(n.start,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2arc(n.end,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2point(e.start,n.start),i.push([s,o]),[s,o]=t.point2point(e.start,n.end),i.push([s,o]),[s,o]=t.point2point(e.end,n.start),i.push([s,o]),[s,o]=t.point2point(e.end,n.end),i.push([s,o]),t.sort(i),i[0]}}static point2polygon(e,n){let s=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let o of n.edges){let[n,i]=t.point2edge(e,o);Xi.Utils.LT(n,s[0])&&(s=[n,i])}return s}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let s of e.edges){let[e,o]=t.distanceTo(s.shape);Xi.Utils.LT(e,n[0])&&(n=[e,o])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let s of t.edges)for(let t of e.edges){let[e,o]=s.shape.distanceTo(t.shape);Xi.Utils.LT(e,n[0])&&(n=[e,o])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),s=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),o=n*n+s*s,i=t.merge(e),r=i.xmax-i.xmin,a=i.ymax-i.ymin;return[o,r*r+a*a]}static minmax_tree_process_level(e,n,s,o){let i,r;for(let a of n){[i,r]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof Xi.Edge?o.insert([i,r],t.shape):o.insert([i,r],t);Xi.Utils.LT(r,s)&&(s=r)}if(0===n.length)return s;let a=[...n.map(t=>t.left.isNil()?void 0:t.left).filter(t=>void 0!==t),...n.map(t=>t.right.isNil()?void 0:t.right).filter(t=>void 0!==t)].filter(n=>{let[o,i]=t.box2box_minmax(e.box,n.max);return Xi.Utils.LE(o,s)});return s=t.minmax_tree_process_level(e,a,s,o)}static minmax_tree(e,n,s){let o=new Sa,i=[n.index.root],r=s<Number.POSITIVE_INFINITY?s*s:Number.POSITIVE_INFINITY;return r=t.minmax_tree_process_level(e,i,r,o),o}static minmax_tree_calc_distance(e,n,s){let o,i;if(null!=n&&!n.isNil()){if([o,i]=t.minmax_tree_calc_distance(e,n.left,s),i)return[o,i];if(Xi.Utils.LT(o[0],Math.sqrt(n.item.key.low)))return[o,!0];let[r,a]=t.distanceToArray(e,n.item.values);return Xi.Utils.LT(r,o[0])&&(o=[r,a]),[o,i]=t.minmax_tree_calc_distance(e,n.right,o),[o,i]}return[s,!1]}static shape2planarSet(e,n,s=Number.POSITIVE_INFINITY){let o=[s,new Xi.Segment],i=!1;if(n instanceof Xi.PlanarSet){let r=t.minmax_tree(e,n,s);[o,i]=t.minmax_tree_calc_distance(e,r.root,o)}return o}static sort(t){t.sort((t,e)=>Xi.Utils.LT(t[0],e[0])?-1:Xi.Utils.GT(t[0],e[0])?1:0)}static distance(t,e){return t.distanceTo(e)}static distanceToArray(t,e){let n=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let s of e){let[e,o]=t.distanceTo(s);Xi.Utils.LT(e,n[0])&&(n=[e,o])}return n}static shape2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let o of n){let[n,i]=t.distance(e,o.shape);Xi.Utils.LT(n,s[0])&&(s=[n,i])}return s}static multiline2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new Xi.Segment];for(let o of e)for(let e of n){let[n,i]=t.distance(o.shape,e.shape);Xi.Utils.LT(n,s[0])&&(s=[n,i])}return s}};var{Multiline:Fa,Point:Ya,Segment:Xa,Polygon:ka}=Xi;function $a(t){return new Ya(t.split(" ").map(Number))}function Ba(t){return t.split(", ").map($a)}function ja(t){const e=Ba(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new Xa(e[t],e[t+1]));return new Fa(n)}function Wa(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new ka;let s;return e.forEach((t,e)=>{let o=t.split(", ").map(t=>new Ya(t.split(" ").map(Number)));const i=n.addFace(o);0===e?s=i.orientation():i.orientation()===s&&i.reverse()}),n}function Ha(t){if(t.startsWith("POLYGON")){return Wa(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(Wa),n=new ka;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function Ua(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function Va(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}Xi.isWktString=function(t){return t.startsWith("POINT")||Ua(t)||t.startsWith("LINESTRING")||Va(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},Xi.parseWKT=function t(e){if(e.startsWith("POINT")){return $a(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return Ba(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return ja(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(ja)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return Ha(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,s=e.match(n);s[0].startsWith("GEOMETRYCOLLECTION")&&(s[0]=s[0].replace("GEOMETRYCOLLECTION (",""));return s.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return Ua(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map($a)}(e):Va(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(ja).reduce((t,e)=>[...t,...e],[])}(e):[]},Xi.BooleanOperations=na,Xi.Relations=ya;var Ga,Za,qa,Ja=(Ga=fo(),Za=1,qa=null!=Ga?Gs(Ks(Ga)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Js(e))Qs.call(t,o)||o===n||Zs(t,o,{get:()=>e[o],enumerable:!(s=qs(e,o))||s.enumerable});return t})(!Za&&Ga&&Ga.__esModule?qa:Zs(qa,"default",{value:Ga,enumerable:!0}),Ga)),Ka=Object.create,Qa=Object.defineProperty,tc=Object.getOwnPropertyDescriptor,ec=Object.getOwnPropertyNames,nc=Object.getPrototypeOf,sc=Object.prototype.hasOwnProperty,oc=(t,e)=>function(){return e||(0,t[ec(t)[0]])((e={exports:{}}).exports,e),e.exports},ic=(t,e,n)=>(n=null!=t?Ka(nc(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of ec(e))sc.call(t,o)||o===n||Qa(t,o,{get:()=>e[o],enumerable:!(s=tc(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Qa(n,"default",{value:t,enumerable:!0}),t)),rc=oc({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),ac=oc({"node_modules/kind-of/index.js"(t,e){var n=rc(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),cc=oc({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),hc=oc({"node_modules/deep-rename-keys/index.js"(t,e){var n=ac(),s=cc();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),lc=oc({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),dc=oc({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=lc(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),uc=oc({"node_modules/xml-reader/dist/reader.js"(t,e){var n=lc(),s=dc(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:pc,sin:fc,PI:mc}=Math,{tan:gc}=Math;ic(hc()),ic(uc());function yc(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var xc=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function vc(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var bc=class extends xc{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(yc(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(yc(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(yc(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Pc=t=>{const{o:e,a:n,b:s}=t;return(n.x-e.x)*(s.y-e.y)-(n.y-e.y)*(s.x-e.x)},Sc=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||Pc({o:e,a:n,b:t})>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||Pc({o:t,a:n,b:e})>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},Mc=t=>void 0!==t,Nc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(Mc)),hulls:n.cells.map(t=>Sc(t,n.pts).map(t=>n.pts[t]).filter(Mc))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},Ic=t=>{const{polygon:e,clearance:n,verticesOnly:s=!1}=t,o=e.points,i=o.length;if(i<3)return[];const r=new Ra(o.map(t=>Ia(t.x,t.y))).orientation()===Ei.CCW,a=[];for(let t=0;t<i;t++){const e=o[t],s=o[(t+1)%i],c=_a(s.x-e.x,s.y-e.y);if(0===c.length){a.push(Ea(Ia(e.x,e.y),_a(1,0)));continue}const h=c.normalize(),l=r?_a(h.y,-h.x):_a(-h.y,h.x),d=Ia(e.x+n*l.x,e.y+n*l.y);a.push(Ea(d,l))}const c=[];for(let t=0;t<i;t++){const e=a[(t-1+i)%i],n=a[t],s=e.intersect(n);if(s.length>0){const t=s[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(s)return c;const h=[];for(let t=0;t<i;t++){const e=c[t],n=c[(t+1)%i],s=Ca(Ia(e.x,e.y),Ia(n.x,n.y)).length,o=Math.max(2,Math.ceil(s/20));for(let t=0;t<o;t++){const s=t/o;h.push({x:e.x+s*(n.x-e.x),y:e.y+s*(n.y-e.y)})}}return h},_c=t=>{const{localX:e,localY:n,rect:s}=t,o=Math.cos(s.ccwRotation),i=Math.sin(s.ccwRotation);return{x:s.center.x+e*o-n*i,y:s.center.y+e*i+n*o}},Cc=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=24}=t,a=[],{minX:c,maxX:h,minY:l,maxY:d}=e;a.push({x:c,y:l},{x:h,y:l},{x:h,y:d},{x:c,y:d});for(let t=1;t<10;t++){const e=t/10;a.push({x:c+e*(h-c),y:l}),a.push({x:h,y:l+e*(d-l)}),a.push({x:h-e*(h-c),y:d}),a.push({x:c,y:d-e*(d-l)})}for(const t of n){const e=t.diameter/2+s;for(let n=0;n<r;n++){const s=2*Math.PI*n/r;a.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let s=0;s<o;s++){const i=s/o;a.push(_c({localX:2*i*e-e,localY:-n,rect:t})),a.push(_c({localX:e,localY:2*i*n-n,rect:t})),a.push(_c({localX:e-2*i*e,localY:n,rect:t})),a.push(_c({localX:-e,localY:n-2*i*n,rect:t}))}}for(const t of i){if(t.points.length<3)continue;const e=Ic({polygon:t,clearance:s});a.push(...e)}return a.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},Tc=(t,e,n)=>{const s=e.length;e.push(...t);const o=t.length;for(let t=0;t<o;t++)n.push([s+t,s+(t+1)%o])},Ec=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=8}=t,a=[],c=[],h=[],{minX:l,maxX:d,minY:u,maxY:p}=e,f=10,m=[];for(let t=0;t<f;t++){const e=t/f;m.push({x:l+e*(d-l),y:u})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d,y:u+e*(p-u)})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d-e*(d-l),y:p})}for(let t=0;t<f;t++){const e=t/f;m.push({x:l,y:p-e*(p-u)})}h.push(c.length),Tc(m,a,c);for(const t of n){const e=t.diameter/2+s,n=[];for(let s=0;s<r;s++){const o=2*Math.PI*s/r;n.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}h.push(c.length),Tc(n,a,c)}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=[_c({localX:-e,localY:-n,rect:t}),_c({localX:e,localY:-n,rect:t}),_c({localX:e,localY:n,rect:t}),_c({localX:-e,localY:n,rect:t})];h.push(c.length),Tc(o,a,c)}for(const t of i){if(t.points.length<3)continue;const e=Ic({polygon:t,clearance:s,verticesOnly:!0});h.push(c.length),Tc(e,a,c)}const g=((t,e,n)=>{const s=new Array(e.length);for(let t=0;t<e.length;t++)for(let e=n.length-1;e>=0;e--)if(t>=n[e]){s[t]=e;break}const o=new Map,i=t.slice();for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++){if(s[t]===s[n])continue;const[r,a]=e[t],[c,h]=e[n],l=i[r],d=i[a],u=i[c],p=i[h],f=d.x-l.x,m=d.y-l.y,g=p.x-u.x,y=p.y-u.y,x=f*y-m*g;if(Math.abs(x)<1e-10)continue;const v=((u.x-l.x)*y-(u.y-l.y)*g)/x,b=((u.x-l.x)*m-(u.y-l.y)*f)/x;if(v>1e-6&&v<.999999&&b>1e-6&&b<.999999){const e=l.x+v*f,s=l.y+v*m,r=i.length;i.push({x:e,y:s}),o.has(t)||o.set(t,[]),o.get(t).push({t:v,idx:r}),o.has(n)||o.set(n,[]),o.get(n).push({t:b,idx:r})}}if(0===o.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const r=[];for(let t=0;t<e.length;t++){const n=o.get(t);if(!n||0===n.length){r.push(e[t]);continue}n.sort((t,e)=>t.t-e.t);const[s,i]=e[t];let a=s;for(const t of n)r.push([a,t.idx]),a=t.idx;r.push([a,i])}return{pts:i,constraintEdges:r,hadCrossings:!0}})(a,c,h);return{pts:g.pts.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:g.constraintEdges,hadCrossings:g.hadCrossings}},wc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];if(!1!==this.input.useConstrainedDelaunay){const s=Ec({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments});this.output={pts:s.pts,constraintEdges:s.constraintEdges,hadCrossings:s.hadCrossings}}else this.output={pts:Cc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments})};this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},Rc=t=>{const{p:e,a:n,b:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(r<1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*o+(e.y-n.y)*i)/r;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*o,e.y-n.y-a*i)},Oc=(t,e)=>{if(t.length<=3)return 0;const n=Sc(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,Rc({p:t,a:n,b:s})))}i=Math.max(i,r)}return i},Ac=(t,e)=>t<e?1e5*t+e:1e5*e+t,zc=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(Ac(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(Ac(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(Ac(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},Lc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Dc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=(t=>{const{triangles:e,pts:n,concavityTolerance:s}=t;if(!e.length)return{cells:[],depths:[]};const o=e.map(([t,e,s])=>{const o=n[t],i=n[e],r=n[s];return o&&i&&r&&Pc({o:o,a:i,b:r})<0?[t,s,e]:[t,e,s]});let i=!0,r=0;for(;i&&r++<800;){i=!1;const t=new Map,e=o.map(()=>new Set);for(let n=0;n<o.length;n++){const s=o[n];if(s)for(let o=0;o<s.length;o++){const i=s[o],r=s[(o+1)%s.length];if(void 0===i||void 0===r)continue;const a=Lc(i,r);if(t.has(a)){const s=t.get(a);void 0!==s&&(e[n]?.add(s),e[s]?.add(n))}else t.set(a,n)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<o.length;t++){const i=e[t];if(i)for(const e of i){if(e<=t)continue;const i=zc(o[t]??[],o[e]??[]);if(!i)continue;const l=Oc(i,n);l<=s+1e-6&&l<h&&(h=l,r=t,a=e,c=i)}}if(r<0||a<0||!c)break;o[r]=c,o.splice(a,1),i=!0}const a=o.map(t=>Oc(t,n));return{cells:o,depths:a}})({triangles:this.input.validTris,pts:this.input.pts,concavityTolerance:this.input.concavityTolerance});this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},Fc=t=>{const{a:e,b:n,c:s}=t,o=2*(e.x*(n.y-s.y)+n.x*(s.y-e.y)+s.x*(e.y-n.y));if(Math.abs(o)<1e-10)return{x:0,y:0,r2:1e18};const i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=s.x*s.x+s.y*s.y,c=(i*(n.y-s.y)+r*(s.y-e.y)+a*(e.y-n.y))/o,h=(i*(s.x-n.x)+r*(e.x-s.x)+a*(n.x-e.x))/o;return{x:c,y:h,r2:(e.x-c)**2+(e.y-h)**2}},Yc=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),Xc=t=>{const{px:e,py:n,polygonPoints:s,clearance:o}=t;if(s.length<3)return!1;const i=s.map(t=>Ia(t.x,t.y)),r=[];for(let t=0;t<i.length;t++){const e=i[t],n=i[(t+1)%i.length];r.push(Ca(e,n))}const a=new Ra;a.addFace(r);const c=Ia(e,n);if(a.contains(c))return!0;const[h]=a.distanceTo(c);return h<o-.1},kc=t=>{const{triangles:e,pts:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t;return e.filter(([t,e,c])=>{const h=n[t],l=n[e],d=n[c];if(!h||!l||!d)return!1;if(!(t=>{const{px:e,py:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t,{minX:c,maxX:h,minY:l,maxY:d}=s;if(e<c-.1||e>h+.1||n<l-.1||n>d+.1)return!1;for(const t of o){const s=t.diameter/2+i;if((e-t.center.x)**2+(n-t.center.y)**2<s*s-.1)return!1}for(const t of r){const s=t.width/2+i,o=t.height/2+i,r=e-t.center.x,a=n-t.center.y,c=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<o-.1)return!1}for(const t of a)if(Xc({px:e,py:n,polygonPoints:t.points,clearance:i}))return!1;return!0})({px:(h.x+l.x+d.x)/3,py:(h.y+l.y+d.y)/3,bounds:s,vias:o,clearance:i,rects:r,polygons:a}))return!1;if(a.length>0){const t=[h,l,d,{x:(h.x+l.x)/2,y:(h.y+l.y)/2},{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2}];for(const e of t)for(const t of a)if(Xc({px:e.x,py:e.y,polygonPoints:t.points,clearance:i}))return!1}return!0})},$c=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];let s;if(!1!==this.input.useConstrainedDelaunay&&this.input.constraintEdges){const o=((t,e)=>{const n=t.map(t=>[t.x,t.y]);return(0,Ja.default)(n,e,{exterior:!1})})(this.input.pts,this.input.constraintEdges);s=this.input.hadCrossings?kc({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n}):o}else{const o=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:Fc({a:h,b:l,c:d})}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&Yc(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:Fc({a:e,b:n,c:t})})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts);s=kc({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n})}this.output={pts:this.input.pts,validTris:s},this.stats={validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},Bc=class extends bc{pipelineDef=[vc("generatePoints",wc,t=>[t.inputProblem]),vc("triangulate",$c,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,polygons:t.inputProblem.polygons,clearance:t.inputProblem.clearance,useConstrainedDelaunay:t.inputProblem.useConstrainedDelaunay,constraintEdges:e.constraintEdges,hadCrossings:e.hadCrossings}]}),vc("mergeCells",Dc,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),vc("buildRegions",Nc,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();if(!t)return{points:[],lines:[],rects:[],circles:[],texts:[]};const e=(this.inputProblem.polygons??[]).flatMap(t=>{const e=t.points;return e.map((t,n)=>{const s=e[(n+1)%e.length];return{points:[{x:t.x,y:t.y},{x:s.x,y:s.y}],strokeColor:"#ff9f43",strokeWidth:2}})}),n=(this.inputProblem.rects??[]).flatMap(t=>{const e=t.width/2,n=t.height/2,s=Math.cos(t.ccwRotation),o=Math.sin(t.ccwRotation),i=[{lx:-e,ly:-n},{lx:e,ly:-n},{lx:e,ly:n},{lx:-e,ly:n}].map(({lx:e,ly:n})=>({x:t.center.x+e*s-n*o,y:t.center.y+e*o+n*s}));return i.map((t,e)=>{const n=i[(e+1)%i.length];return{points:[{x:t.x,y:t.y},{x:n.x,y:n.y}],strokeColor:"#ff6b6b",strokeWidth:2}})});return{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:[...t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),...e,...n],rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}}};function jc(t,e,n,s,o){const i=e.x-t.x,r=e.y-t.y,a=s.x-n.x,c=s.y-n.y,h=i*c-r*a,l=Math.sqrt(i*i+r*r),d=Math.sqrt(a*a+c*c);if(l<o||d<o)return!1;if(Math.abs(h)/(l*d)>o)return!1;const u=n.x-t.x,p=n.y-t.y;return Math.abs(i*p-r*u)/l<o}function Wc(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-12){return{t:0,distance:Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}}const r=((t.x-e.x)*s+(t.y-e.y)*o)/i,a=e.x+r*s,c=e.y+r*o;return{t:r,distance:Math.sqrt((t.x-a)**2+(t.y-c)**2)}}function Hc(t,e,n,s){const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s),a=Math.max(n,s),c=Math.max(o,r),h=Math.min(i,a);return h-c<1e-6?null:{from:c,to:h}}function Uc(t,e,n=.01){const s=[];for(let o=0;o<t.length;o++){const i=t[o],r=t[(o+1)%t.length];for(let t=0;t<e.length;t++){const o=e[t],a=e[(t+1)%e.length];if(!jc(i,r,o,a,n))continue;const c=Wc(o,i,r),h=Wc(a,i,r);if(c.distance>n||h.distance>n)continue;const l=Hc(0,1,c.t,h.t);if(!l)continue;const d=r.x-i.x,u=r.y-i.y,p={x:i.x+l.from*d,y:i.y+l.from*u},f={x:i.x+l.to*d,y:i.y+l.to*u};s.push({from:p,to:f})}}return s}function Vc(t,e=.4){const n=t.to.x-t.from.x,s=t.to.y-t.from.y,o=Math.sqrt(n*n+s*s);if(o<.001)return[];const i=Math.max(1,Math.floor(o/e)),r=[];for(let e=0;e<i;e++){const o=(e+.5)/i;r.push({x:t.from.x+o*n,y:t.from.y+o*s})}return r}function Gc(t,e=.001){if(t.length<=1)return t;const n=[t[0]];for(let s=1;s<t.length;s++){const o=n[n.length-1],i=t[s];Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)>e&&n.push(i)}if(n.length>1){const t=n[0],s=n[n.length-1];Math.sqrt((s.x-t.x)**2+(s.y-t.y)**2)<e&&n.pop()}return n}function Zc(t){let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)i.x<e&&(e=i.x),i.x>n&&(n=i.x),i.y<s&&(s=i.y),i.y>o&&(o=i.y);return{minX:e,maxX:n,minY:s,maxY:o}}function qc(t){let e=0,n=0;for(const s of t)e+=s.x,n+=s.y;return{x:e/t.length,y:n/t.length}}function Jc(t,e,n){return{regionId:t,ports:[],d:{bounds:Zc(e),center:qc(e),polygon:e,isPad:!1,isViaRegion:n?.isViaRegion}}}function Kc(t){if(0===t.length)return[];const e=t.reduce((t,e)=>e.position.y>t.position.y?e:t),n=t.reduce((t,e)=>e.position.y<t.position.y?e:t),s=t.reduce((t,e)=>e.position.x<t.position.x?e:t),o=t.reduce((t,e)=>e.position.x>t.position.x?e:t),i={xStart:e.position.x-e.diameter/2,xEnd:e.position.x+e.diameter/2,y:e.position.y+e.diameter/2},r={xStart:n.position.x-n.diameter/2,xEnd:n.position.x+n.diameter/2,y:n.position.y-n.diameter/2},a={x:s.position.x-s.diameter/2,yStart:s.position.y-s.diameter/2,yEnd:s.position.y+s.diameter/2},c={x:o.position.x+o.diameter/2,yStart:o.position.y-o.diameter/2,yEnd:o.position.y+o.diameter/2};return Gc([{x:i.xStart,y:i.y},{x:i.xEnd,y:i.y},{x:c.x,y:c.yEnd},{x:c.x,y:c.yStart},{x:r.xEnd,y:r.y},{x:r.xStart,y:r.y},{x:a.x,y:a.yStart},{x:a.x,y:a.yEnd}])}function Qc(t,e,n,s){return t.map(t=>({viaId:`${s}:${t.viaId}`,diameter:t.diameter,position:{x:t.position.x+e,y:t.position.y+n}}))}function th(t,e,n,s){return t.map(t=>({routeId:`${s}:${t.routeId}`,fromPort:`${s}:${t.fromPort}`,toPort:`${s}:${t.toPort}`,layer:t.layer,segments:t.segments.map(t=>({x:t.x+e,y:t.y+n}))}))}function eh(t,e,n){return t.map(t=>({x:t.x+e,y:t.y+n}))}function nh(t){return[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}]}function sh(t){if(t.length<3)return{top:null,bottom:null,left:null,right:null};const e=Zc(t),n=.001;let s=null,o=null,i=null,r=null;for(let a=0;a<t.length;a++){const c=t[a],h=t[(a+1)%t.length];Math.abs(c.y-e.maxY)<n&&Math.abs(h.y-e.maxY)<n&&(s={x:(c.x+h.x)/2,y:e.maxY}),Math.abs(c.y-e.minY)<n&&Math.abs(h.y-e.minY)<n&&(o={x:(c.x+h.x)/2,y:e.minY}),Math.abs(c.x-e.minX)<n&&Math.abs(h.x-e.minX)<n&&(i={x:e.minX,y:(c.y+h.y)/2}),Math.abs(c.x-e.maxX)<n&&Math.abs(h.x-e.maxX)<n&&(r={x:e.maxX,y:(c.y+h.y)/2})}return{top:s,bottom:o,left:i,right:r}}function oh(t,e,n=.1){if(0===t.length)return t;const s=Zc(t),o=s.minX-e.minX,i=e.maxX-s.maxX,r=s.minY-e.minY,a=e.maxY-s.maxY,c=o>0&&o<n,h=i>0&&i<n,l=r>0&&r<n,d=a>0&&a<n;if(!(c||h||l||d))return t;return Gc(t.map(t=>{let n=t.x,o=t.y;return c&&Math.abs(t.x-s.minX)<.001&&(n=e.minX),h&&Math.abs(t.x-s.maxX)<.001&&(n=e.maxX),l&&Math.abs(t.y-s.minY)<.001&&(o=e.minY),d&&Math.abs(t.y-s.maxY)<.001&&(o=e.maxY),{x:n,y:o}}))}function ih(t,e){let n=!1;const s=e.length;for(let o=0,i=s-1;o<s;i=o++){const s=e[o].x,r=e[o].y,a=e[i].x,c=e[i].y;if(Math.abs((t.y-r)*(a-s)-(t.x-s)*(c-r))<.001&&t.x>=Math.min(s,a)-.001&&t.x<=Math.max(s,a)+.001&&t.y>=Math.min(r,c)-.001&&t.y<=Math.max(r,c)+.001)return!0;if(r>t.y!=c>t.y){const e=(a-s)*(t.y-r)/(c-r)+s;t.x<e&&(n=!n)}}return n}function rh(t,e){for(const n of e)if(n.d.polygon&&ih(t,n.d.polygon))return n;return null}function ah(t){const e=t.tileWidth??t.tileSize??t.viaTile.tileWidth,n=t.tileHeight??t.tileSize??t.viaTile.tileHeight;if(void 0===e||void 0===n)throw new Error("tileWidth and tileHeight must be provided either in opts or in viaTile");const s=t.portPitch??.4,o=t.clearance??.1,i=t.concavityTolerance??0,{bounds:r,viaTile:a}=t,{viasByNet:c,routeSegments:h}=a,l=r.maxX-r.minX,d=r.maxY-r.minY,u=Math.floor(l/e),p=Math.floor(d/n),f=[],m=[],g={viasByNet:{},routeSegments:[]},y=[],x=[],v=u*e,b=p*n,P=r.minX+(l-v)/2,S=r.minY+(d-b)/2,M=P+v,N=S+b,I=e/2,_=n/2;let C=0;const T=new Set,E=(t,e,n,s)=>{const o=(i=s.x,r=s.y,`${i.toFixed(4)},${r.toFixed(4)}`);var i,r;if(T.has(o))return null;T.add(o);const a={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(a),n.ports.push(a),m.push(a),a};let w=null;if(p>0&&u>0&&(w=function(t,e,n,s,o){const i=e/2,r=n/2,a={minX:-i,maxX:i,minY:-r,maxY:r},c=[];for(const[e,n]of Object.entries(t.viasByNet)){if(0===n.length)continue;const t=Kc(n);0!==t.length&&c.push({netName:e,polygon:t,bounds:Zc(t),center:qc(t)})}const h=c.map(t=>({points:oh(t.polygon,a)})),l=new Bc({bounds:a,polygons:h,clearance:s,concavityTolerance:o});l.solve();const d=l.getOutput();if(!d)throw new Error("ConvexRegionsSolver failed to compute unit tile regions");return{viaRegions:c,convexRegions:d.regions.map(t=>({polygon:t,bounds:Zc(t),center:qc(t)})),tileWidth:e,tileHeight:n}}(a,e,n,o,i)),p>0&&u>0&&w)for(let t=0;t<p;t++)for(let s=0;s<u;s++){const o=P+s*e+I,i=S+t*n+_,r=`t${t}_${s}`;for(const t of w.viaRegions){const e=eh(t.polygon,o,i),n=Jc(`${r}:v:${t.netName}`,e,{isViaRegion:!0});y.push(n),f.push(n)}for(let t=0;t<w.convexRegions.length;t++){const e=Jc(`${r}:convex:${t}`,eh(w.convexRegions[t].polygon,o,i));x.push(e),f.push(e)}for(const[t,e]of Object.entries(c)){if(0===e.length)continue;const n=Qc(e,o,i,r);g.viasByNet[t]||(g.viasByNet[t]=[]),g.viasByNet[t].push(...n)}g.routeSegments.push(...th(h,o,i,r))}const R=[],O=r.maxY-N,A=S-r.minY,z=P-r.minX,L=r.maxX-M,D=Math.max(O,A)>=Math.max(z,L),F=D?r.minX:P,Y=D?r.maxX:M,X=D?r.minX:P,k=D?r.maxX:M,$=D?S:r.minY,B=D?N:r.maxY,j=D?S:r.minY,W=D?N:r.maxY;if(O>.001){const t=Y-F,e=Math.max(O,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Jc(`filler:top:${t}`,nh({minX:F+t*o,maxX:F+(t+1)*o,minY:N,maxY:r.maxY}));R.push(e),f.push(e)}}if(A>.001){const t=k-X,e=Math.max(A,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Jc(`filler:bottom:${t}`,nh({minX:X+t*o,maxX:X+(t+1)*o,minY:r.minY,maxY:S}));R.push(e),f.push(e)}}if(z>.001){const t=B-$,e=Math.max(z,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Jc(`filler:left:${t}`,nh({minX:r.minX,maxX:P,minY:$+t*o,maxY:$+(t+1)*o}));R.push(e),f.push(e)}}if(L>.001){const t=W-j,e=Math.max(L,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Jc(`filler:right:${t}`,nh({minX:M,maxX:r.maxX,minY:j+t*o,maxY:j+(t+1)*o}));R.push(e),f.push(e)}}if(w&&p>0&&u>0){const t=w.convexRegions.length;for(let e=0;e<p;e++)for(let n=0;n<u;n++){const i=(e*u+n)*t;for(let r=0;r<t;r++)for(let a=r+1;a<t;a++){const t=x[i+r],c=x[i+a],h=Uc(t.d.polygon,c.d.polygon,2*o);for(const o of h){const i=Vc(o,s);for(const s of i)E(`t${e}_${n}:convex:${r}-${a}:${C++}`,t,c,s)}}}}if(w&&p>0&&u>0){const t=w.convexRegions.length,o=w.viaRegions.length,i=Math.floor(n/s),r=[];for(let t=0;t<i;t++)r.push((t+.5)*s-_);const a=Math.floor(e/s),c=[];for(let t=0;t<a;t++)c.push((t+.5)*s-I);for(let s=0;s<p;s++)for(let i=0;i<u;i++){const a=s*u+i,h=a*t,l=a*o,d=P+i*e+I,f=S+s*n+_,m=[...x.slice(h,h+t),...y.slice(l,l+o)];if(i+1<u){const e=s*u+(i+1),n=e*t,a=e*o,c=[...x.slice(n,n+t),...y.slice(a,a+o)],h=d+I;for(const t of r){const e=f+t,n={x:h+.01,y:e},o=rh({x:h-.01,y:e},m),r=rh(n,c);o&&r&&E(`tile:${s}_${i}-${s}_${i+1}:${C++}`,o,r,{x:h,y:e})}}if(s+1<p){const e=(s+1)*u+i,n=e*t,r=e*o,a=[...x.slice(n,n+t),...y.slice(r,r+o)],h=f+_;for(const t of c){const e=d+t,n={x:e,y:h+.01},o=rh({x:e,y:h-.01},m),r=rh(n,a);o&&r&&E(`tile:${s}_${i}-${s+1}_${i}:${C++}`,o,r,{x:e,y:h})}}}}const H=new Map;for(const t of R){H.set(t.regionId,[]);const e=t.d.bounds,n=e.maxX-e.minX,i=e.maxY-e.minY,r=n>i,a=r?n:i,c=(Math.max(1,Math.floor(a/s)),2*o),h=t.regionId.startsWith("filler:top:"),l=t.regionId.startsWith("filler:bottom:"),d=t.regionId.startsWith("filler:left:"),u=t.regionId.startsWith("filler:right:"),p=[...x,...y];for(const n of p){const o=n.d.bounds,i=.001;let a,p,f=!1,m=null,g=null;if(r){const t=Math.max(e.minX,o.minX);Math.min(e.maxX,o.maxX)>t+i&&(h?(f=Math.abs(o.maxY-e.minY)<c,g=e.minY):l&&(f=Math.abs(o.minY-e.maxY)<c,g=e.maxY))}else{const t=Math.max(e.minY,o.minY);Math.min(e.maxY,o.maxY)>t+i&&(d?(f=Math.abs(o.minX-e.maxX)<c,m=e.maxX):u&&(f=Math.abs(o.maxX-e.minX)<c,m=e.minX))}if(!f)continue;r?(a=Math.max(e.minX,o.minX),p=Math.min(e.maxX,o.maxX)):(a=Math.max(e.minY,o.minY),p=Math.min(e.maxY,o.maxY));const y=p-a;if(y<i)continue;const x=Math.max(1,Math.floor(y/s)),v=y/x;for(let i=0;i<x;i++){let c;if(r){c={x:a+(i+.5)*v,y:g}}else{c={x:m,y:a+(i+.5)*v}}if(n.d.polygon){let t;if(h){const n=e.minY-o.maxY+.01;t={x:c.x,y:c.y-n}}else if(l){const n=o.minY-e.maxY+.01;t={x:c.x,y:c.y+n}}else if(d){const n=o.minX-e.maxX+.01;t={x:c.x+n,y:c.y}}else{const n=e.minX-o.maxX+.01;t={x:c.x-n,y:c.y}}if(!ih(t,n.d.polygon))continue}const u=H.get(t.regionId);u.some(t=>Math.sqrt((c.x-t.x)**2+(c.y-t.y)**2)<s)||(u.push(c),E(`filler:${n.regionId}-${t.regionId}:${C++}`,n,t,c))}}}for(let t=0;t<R.length;t++)for(let e=t+1;e<R.length;e++){const n=R[t],o=R[e],i=Uc(n.d.polygon,o.d.polygon,.01);for(const t of i){const e=Math.sqrt((t.to.x-t.from.x)**2+(t.to.y-t.from.y)**2);if(e<.01)continue;let i;i=e<s?[{x:(t.from.x+t.to.x)/2,y:(t.from.y+t.to.y)/2}]:Vc(t,s);for(const t of i)E(`filler:${n.regionId}-${o.regionId}:${C++}`,n,o,t)}}const U=f.filter(t=>!t.d.isViaRegion),V=new Set;for(const t of y){const e=sh(t.d.polygon),n=t.d.bounds,s=["top","bottom","left","right"];for(const o of s){const s=e[o];if(!s)continue;const i=`${t.regionId}:${o}`;if(V.has(i))continue;const r=.2,a=r;let c;switch(o){case"top":c={x:s.x,y:n.maxY+a};break;case"bottom":c={x:s.x,y:n.minY-a};break;case"left":c={x:n.minX-a,y:s.y};break;case"right":c={x:n.maxX+a,y:s.y}}for(const e of U){const a=e.d.bounds;let h=!1;switch(o){case"top":h=Math.abs(a.minY-n.maxY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"bottom":h=Math.abs(a.maxY-n.minY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"left":h=Math.abs(a.maxX-n.minX)<r&&a.minY<s.y&&a.maxY>s.y;break;case"right":h=Math.abs(a.minX-n.maxX)<r&&a.minY<s.y&&a.maxY>s.y}if(h&&(e.d.polygon&&ih(c,e.d.polygon))){E(`via-side:${t.regionId}:${o}:${C++}`,t,e,s),V.add(i);break}}}}return{regions:f,ports:m,viaTile:g,tileCount:{rows:p,cols:u}}}function ch(t,e=ri,n){const s=function(t){if(0===t.length)throw new Error("Cannot calculate bounds from empty connections array");let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)e=Math.min(e,i.start.x,i.end.x),n=Math.max(n,i.start.x,i.end.x),s=Math.min(s,i.start.y,i.end.y),o=Math.max(o,i.start.y,i.end.y);return{minX:e,maxX:n,minY:s,maxY:o}}(t),{regions:o,ports:i,viaTile:r,tileCount:a}=ah({viaTile:e,bounds:s,tileWidth:n?.tileWidth??e.tileWidth,tileHeight:n?.tileHeight??e.tileHeight,tileSize:n?.tileSize,portPitch:n?.portPitch,clearance:n?.clearance,concavityTolerance:n?.concavityTolerance}),c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[];for(const i of e){const{start:e,end:r,connectionId:a}=i,c=Jo(`conn:${a}:start`,e.x,e.y);n.push(c);const h=Jo(`conn:${a}:end`,r.x,r.y);n.push(h);const l=Ci({x:e.x,y:e.y,regions:t.regions});if(l){const t=qo(`conn:${a}:start-port`,c,l.region,l.portPosition);s.push(t)}const d=Ci({x:r.x,y:r.y,regions:t.regions});if(d){const t=qo(`conn:${a}:end-port`,h,d.region,d.portPosition);s.push(t)}const u={connectionId:a,mutuallyConnectedNetworkId:a,startRegion:c,endRegion:h};o.push(u)}return{regions:n,ports:s,connections:o}})({regions:o,ports:i},t);return{...c,viaTile:r,tileCount:a}}var hh=class extends Ln{getSolverName(){return"FixedTopologyHighDensityIntraNodeSolver"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;viaDiameter;viaTile;connMap;rootConnectionNameByConnectionId=new Map;lastActiveSubSolver=null;solvedRoutes=[];vias=[];tiledViasByNet={};constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaTile=ri,this.viaDiameter=this._resolveViaDiameter(t.viaDiameter),this.connMap=t.connMap,this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=(t=>{const e=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],n={},s=new Set;for(const e of t.portPoints)s.add(e.connectionName);let o=0;for(const t of Array.from(s))n[t]=e[o%e.length],o++;return n})(this.nodeWithPortPoints))}getConstructorParams(){return this.constructorParams}_getViaTileDiameter(t){for(const e of Object.values(t.viasByNet))if(e.length>0)return e[0].diameter;return.3}_resolveViaDiameter(t){const e=this._getViaTileDiameter(this.viaTile);return void 0!==t&&Math.abs(t-e)<=1e-6?t:e}_initializeGraph(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=t.get(e.connectionName);n?n.points.push(e):t.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.rootConnectionNameByConnectionId.clear();const e=[];for(const[n,s]of t.entries())s.points.length<2||(this.rootConnectionNameByConnectionId.set(n,s.rootConnectionName),e.push({connectionId:n,start:{x:s.points[0].x,y:s.points[0].y},end:{x:s.points[s.points.length-1].x,y:s.points[s.points.length-1].y}}));if(0===e.length)return null;const n=ch(e,this.viaTile);return this.tiledViasByNet=n.viaTile.viasByNet??{},new Ii({inputGraph:{regions:n.regions,ports:n.ports},inputConnections:n.connections,viaTile:n.viaTile})}_step(){let t=this.activeSubSolver;if(!t){if(t=this._initializeGraph(),!t)return void(this.solved=!0);this.activeSubSolver=t,this.lastActiveSubSolver=t}t.step(),t.solved?(this._processResults(t),this.lastActiveSubSolver=t,this.activeSubSolver=null,this.solved=!0):t.failed&&(this.error=t.error,this.lastActiveSubSolver=t,this.activeSubSolver=null,this.failed=!0)}_upsertGlobalVia(t,e,n,s){const o=`${e.x.toFixed(4)},${e.y.toFixed(4)}`;t.has(o)||t.set(o,{center:{x:e.x,y:e.y},diameter:n,connectedTo:new Set}),t.get(o).connectedTo.add(s)}_upsertRouteViaRegion(t,e,n,s,o){t.some(t=>Math.abs(t.center.x-e.x)<.01&&Math.abs(t.center.y-e.y)<.01)||t.push({viaRegionId:o,center:{x:e.x,y:e.y},diameter:n,connectedTo:[s]})}_appendRoutePoint(t,e){const n=t[t.length-1];n&&Math.abs(n.x-e.x)<=1e-6&&Math.abs(n.y-e.y)<=1e-6&&n.z===e.z||t.push(e)}_parseViaRegionNetName(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}_parseViaRegionTilePrefix(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}_selectViasForTraversedRegion(t,e){const n=this._parseViaRegionNetName(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=this._parseViaRegionTilePrefix(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}_findNearestVia(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=t*t+i*i;r<s&&(s=r,n=o)}return n}_getBottomRoutePointsBetweenVias(t,e,n,s){if(n.viaId===s.viaId)return[n.position];const o=new Set(e.map(t=>t.viaId)),i=t.routeSegments.filter(t=>"bottom"===t.layer&&t.segments.length>=2&&o.has(t.fromPort)&&o.has(t.toPort)),r=new Map,a=(t,e,n)=>{r.has(t)||r.set(t,[]),r.get(t).push({to:e,points:n})};for(const t of i)a(t.fromPort,t.toPort,t.segments),a(t.toPort,t.fromPort,[...t.segments].reverse());const c=[n.viaId],h=new Set([n.viaId]),l=new Map;for(;c.length>0;){const t=c.shift();if(t===s.viaId)break;for(const e of r.get(t)??[])h.has(e.to)||(h.add(e.to),l.set(e.to,{from:t,points:e.points}),c.push(e.to))}if(!l.has(s.viaId))return null;const d=[];let u=s.viaId;for(;u!==n.viaId;){const t=l.get(u);if(!t)return null;d.push(t.points),u=t.from}d.reverse();const p=[];for(const t of d)for(const e of t){const t=p[p.length-1];(!t||Math.abs(t.x-e.x)>1e-6||Math.abs(t.y-e.y)>1e-6)&&p.push(e)}return p.length>0?p:null}_appendViaUsage(t,e,n,s,o){o&&(this._upsertGlobalVia(t,o.position,o.diameter,n),this._upsertRouteViaRegion(e,o.position,o.diameter,n,s))}_processResults(t){this.solvedRoutes=[];const e=t.viaTile,n=new Map;for(const s of t.solvedRoutes){const t=s.connection.connectionId,o=this.rootConnectionNameByConnectionId.get(t),i=[],r=[],a=s.path;if(0===a.length)continue;const c=a[0].port;this._appendRoutePoint(i,{x:c.d.x,y:c.d.y,z:0});for(let s=1;s<a.length;s++){const o=a[s-1],c=a[s],h={x:o.port.d.x,y:o.port.d.y},l={x:c.port.d.x,y:c.port.d.y},d=c.lastRegion;if(!d?.d?.isViaRegion||!e){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const u=this._selectViasForTraversedRegion(e,d);if(0===u.length){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const p=this._findNearestVia(u,h),f=this._findNearestVia(u,l);if(!p||!f){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const m=this._getBottomRoutePointsBetweenVias(e,u,p,f);if(m&&0!==m.length){this._appendViaUsage(n,r,t,d.regionId,p),this._appendViaUsage(n,r,t,d.regionId,f),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:0}),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:1});for(const t of m)this._appendRoutePoint(i,{x:t.x,y:t.y,z:1});this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:1}),this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:0}),this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}else this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}const h=r.map(t=>({x:t.center.x,y:t.center.y}));this.solvedRoutes.push({connectionName:t,rootConnectionName:o,traceThickness:this.traceWidth,viaDiameter:r.length>0?Math.max(...r.map(t=>t.diameter)):this.viaDiameter,route:i,vias:h,viaRegions:r})}let s=0;this.vias=Array.from(n.values()).map(t=>({viaRegionId:"via_"+s++,center:t.center,diameter:t.diameter,connectedTo:Array.from(t.connectedTo)}))}getOutput(){return this.solvedRoutes}getOutputVias(){return this.vias}visualize(){return this.activeSubSolver?this.activeSubSolver.visualize():this.lastActiveSubSolver?this.lastActiveSubSolver.visualize():super.visualize()}},lh=class extends os{getSolverName(){return"HyperSingleIntraNodeSolver"}constructorParams;solvedRoutes=[];nodeWithPortPoints;connMap;constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.connMap=t.connMap,this.constructorParams=t,this.MAX_ITERATIONS=3e7,this.GREEDY_MULTIPLIER=5,this.MIN_SUBSTEPS=100}getCombinationDefs(){return[["multiHeadPolyLine"],["majorCombinations","orderings6","cellSizeFactor"],["noVias"],["orderings50"],["flipTraceAlignmentDirection","orderings6"],["closedFormSingleTrace"],["highDensityA01"],["fixedTopologyHighDensityIntraNodeSolver"]]}getHyperParameterDefs(){return[{name:"majorCombinations",possibleValues:[{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:2,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:10,MISALIGNED_DIST_PENALTY_FACTOR:5},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:.5,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:2},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:10,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:10,VIA_PENALTY_FACTOR_2:1}]},{name:"orderings6",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5}]},{name:"cellSizeFactor",possibleValues:[{CELL_SIZE_FACTOR:.5},{CELL_SIZE_FACTOR:1}]},{name:"flipTraceAlignmentDirection",possibleValues:[{FLIP_TRACE_ALIGNMENT_DIRECTION:!0}]},{name:"noVias",possibleValues:[{CELL_SIZE_FACTOR:2,VIA_PENALTY_FACTOR_2:10}]},{name:"orderings50",possibleValues:Array.from({length:50},(t,e)=>({SHUFFLE_SEED:100+e}))},{name:"closedFormSingleTrace",possibleValues:[{CLOSED_FORM_SINGLE_TRANSITION:!0}]},{name:"multiHeadPolyLine",possibleValues:[{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:.05},{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:-.05,ITERATION_PENALTY:1e4,MINIMUM_FINAL_ACCEPTANCE_GAP:.001}]},{name:"highDensityA01",possibleValues:[{HIGH_DENSITY_A01:!0}]},{name:"fixedTopologyHighDensityIntraNodeSolver",possibleValues:[{FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER:!0}]}]}computeG(t){return t instanceof Vs?t.iterations/1e6:t?.hyperParameters?.MULTI_HEAD_POLYLINE_SOLVER?1e3+((t.hyperParameters?.ITERATION_PENALTY??0)+t.iterations)/1e4+1e4*(t.hyperParameters.SEGMENTS_PER_POLYLINE-3):t.iterations/1e4}computeH(t){return 1-(t.progress||0)}generateSolver(t){if(t.HIGH_DENSITY_A01){const e=new Vs({nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:.1,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,traceThickness:this.constructorParams.traceWidth??.15,hyperParameters:{shuffleSeed:t.SHUFFLE_SEED??0}});return e.MAX_ITERATIONS=1e7,e}return t.CLOSED_FORM_TWO_TRACE_SAME_LAYER?new rs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?new xs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_SINGLE_TRANSITION?new vs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.MULTI_HEAD_POLYLINE_SOLVER?new Us({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,hyperParameters:t,viaDiameter:this.constructorParams.viaDiameter}):t.FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER?new hh({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,colorMap:this.constructorParams.colorMap,viaDiameter:this.constructorParams.viaDiameter,traceWidth:this.constructorParams.traceWidth}):new ss({...this.constructorParams,hyperParameters:t})}onSolve(t){let e;e=t.solver instanceof Vs?t.solver.getOutput():t.solver.solvedRoutes,this.solvedRoutes=e.map(t=>{const e=this.nodeWithPortPoints.portPoints.find(e=>e.connectionName===t.connectionName);return e?.rootConnectionName?{...t,rootConnectionName:e.rootConnectionName}:t})}},dh=class extends Ln{getSolverName(){return"HighDensitySolver"}unsolvedNodePortPoints;routes;colorMap;defaultViaDiameter=.3;defaultTraceThickness=.15;viaDiameter;traceWidth;failedSolvers;activeSubSolver=null;connMap;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:s,traceWidth:o}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.routes=[],this.failedSolvers=[],this.MAX_ITERATIONS=5e7,this.viaDiameter=s??this.defaultViaDiameter,this.traceWidth=o??this.defaultTraceThickness}_step(){if(this.updateCacheStats(),this.activeSubSolver)return this.activeSubSolver.step(),this.activeSubSolver.solved?(this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null),void this.updateCacheStats();if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length>0?(this.solved=!1,this.failed=!0,this.error=`Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0,5).map(t=>t.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`,void this.updateCacheStats()):(this.solved=!0,void this.updateCacheStats());const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new lh({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth}),this.updateCacheStats()}updateCacheStats(){const t=Se();this.stats.intraNodeCacheHits=t.cacheHits,this.stats.intraNodeCacheMisses=t.cacheMisses}visualize(){let t={lines:[],points:[],rects:[],circles:[]};for(const e of this.routes){const n=jn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:Nn(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});for(const n of e.vias)t.circles.push({center:n,layer:"z0,1",radius:e.viaDiameter/2,fill:this.colorMap[e.connectionName],label:`${e.connectionName} via`})}for(const e of this.failedSolvers){const n=e.nodeWithPortPoints,s=.1*n.width,o=.1*n.height;t.rects.push({center:{x:n.center.x-s/2,y:n.center.y-o/2},layer:"did_not_connect",width:s,height:o,fill:"red",label:`Failed: ${n.capacityMeshNodeId}`});const i={};for(const t of n.portPoints)i[t.connectionName]||(i[t.connectionName]=[]),i[t.connectionName].push({x:t.x,y:t.y,z:t.z});for(const[e,n]of Object.entries(i))for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1];t.lines.push({points:[s,o],strokeColor:"red",strokeDash:"10, 5",layer:"did_not_connect"})}}return this.activeSubSolver&&(t=Bn(t,this.activeSubSolver.visualize())),t}};function uh(t,e){const n=[],s=e.filter(t=>t._containsTarget),o=new Map;for(const i of t.connections){const t=[];for(const n of i.pointsToConnect){let o=e[0],i=Number.MAX_VALUE;for(const t of s){const e=Math.sqrt((t.center.x-n.x)**2+(t.center.y-n.y)**2);e<i&&(i=e,o=t)}t.push(o)}if(t.length<2)throw new Error(`Not enough nodes for connection "${i.name}", only ${t.length} found`);o.set(i.name,t.map(t=>t.capacityMeshNodeId)),n.push({connection:i,nodeIds:[t[0].capacityMeshNodeId,t[t.length-1].capacityMeshNodeId],straightLineDistance:k(t[0].center,t[t.length-1].center)})}return{unshuffledConnectionsWithResults:n,connectionNameToGoalNodeIds:o}}function ph(t,e){const n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=e.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0),o=s.length>0?s.reduce((t,e)=>t+e,0)/s.length:1,i=e.filter(t=>t._offBoardConnectionId),r=new Map,a=new Map,c=new Map;for(const t of e)a.set(t.capacityMeshNodeId,[]),c.set(t.capacityMeshNodeId,[]);for(const t of e)for(const e of t.portPoints){r.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=a.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}=uh(t,e);return{nodeMap:n,avgNodePitch:o,offBoardNodes:i,portPointMap:r,nodePortPointsMap:a,nodeAssignedPortPoints:c,unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}}function fh(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function mh(t,e,n=1e-6){return Math.abs(t-e)<n}function gh(t){if(t.length<2)return 0;const e=t.map(([t,e])=>t<e?[t,e]:[e,t]);let n=0;for(let t=0;t<e.length;t++){const[s,o]=e[t];for(let i=t+1;i<e.length;i++){const[t,r]=e[i];mh(s,t)||mh(s,r)||mh(o,t)||mh(o,r)||(s<t&&t<o&&o<r||t<s&&s<r&&r<o)&&n++}}return n}var yh=t=>{const e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2,i=new Map;for(const e of t.portPoints){const t=i.get(e.connectionName)??[];t.some(t=>t.x===e.x&&t.y===e.y&&t.z===e.z)||t.push({x:e.x,y:e.y,z:e.z}),i.set(e.connectionName,t)}const r=new Map,a=[];let c=0;for(const[t,h]of i){if(h.length<2)continue;const t=h[0],i=h[1],l=fh(t,e,n,s,o),d=fh(i,e,n,s,o);if(t.z===i.z){const e=t.z,n=r.get(e)??[];n.push([l,d]),r.set(e,n)}else c++,a.push([l,d])}let h=0;for(const[t,e]of r)h+=gh(e);return{numSameLayerCrossings:h,numEntryExitLayerChanges:c,numTransitionPairCrossings:gh(a)}},xh=(t,e=1,n={})=>{const s=n.viaDiameter??.3,o=n.obstacleMargin??.2,i=(("width"in t?t.width:t)/(s/2+o)/2)**1.1*e;return 1===t.availableZ?.length&&i>1?1:i},vh=(t,e=.5,n=16)=>{let s=0,o=t;for(;s<n;){if(xh({width:o})<=e)break;o/=2,s++}return Math.max(1,s)},bh=(t,e,n,s)=>{if(t?._containsTarget)return 0;if(1===(t.availableZ?.length??2)&&(e>0||n>0||s>0))return 1;return((.82*e+.41*n+.2*s)/2)**1.1/xh(t)};function Ph(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=yh(n),r=Math.min(bh(t,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings),o);s+=Math.log(1-r)}return s}function Sh(t,e){if(e._containsTarget)return 0;const n=yh(t);return bh(e,n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}function Mh(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}var Nh=1.6*3.2,Ih=(t,e)=>{const n=Math.ceil(e/2),s=Math.min(t.width,t.height),o=Math.max(t.width,t.height),i=(Math.floor(s/1.6)+.1)*(Math.floor(o/3.2)+.1)/Nh;return Math.min(1,n/i)};function _h(t,e,n,s){const o=e.x-n/2,i=e.x+n/2,r=e.y-s/2,a=e.y+s/2,c=Math.abs(t.y-a),h=Math.abs(t.x-i),l=Math.abs(t.y-r),d=Math.abs(t.x-o),u=Math.min(c,h,l,d);return u>.001?"interior":u===c?"top":u===h?"right":u===l?"bottom":"left"}function Ch(t,e,n,s,o){const i=_h(t,n,s,o),r=_h(e,n,s,o);return"interior"!==i&&i===r}function Th(t,e,n,s,o){const i=_h(t,n,s,o);let r;if("top"===i||"bottom"===i){const n=s;r=Math.abs(e.x-t.x)/n}else{const n=o;r=Math.abs(e.y-t.y)/n}r=Math.min(1,Math.max(0,r));const a=(t.x+e.x)/2,c=(t.y+e.y)/2;return{x:a+(n.x-a)*r,y:c+(n.y-c)*r}}function Eh(t){return"computeNodePf"in t&&"function"==typeof t.computeNodePf}function wh(t){const e={lines:[],points:[],rects:[],circles:[]};for(const n of t.inputNodes){let s=0,o=0,i={numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},r=0;if(Eh(t)){s=t.computeNodePf(n),o=t.nodeMemoryPfMap.get(n.capacityMeshNodeId)??0;const e=t.buildNodeWithPortPointsForCrossing(n);i=yh(e);const a=new Set,c=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[];for(const t of c)t.connectionName&&a.add(t.connectionName);r=a.size}else{s=t.nodePfMap.get(n.capacityMeshNodeId)??0;const e=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[],o={capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:e,availableZ:n.availableZ};i=yh(o);const a=new Set;for(const t of e)t.connectionName&&a.add(t.connectionName);r=a.size}const a=Math.min(255,Math.floor(512*s)),c=Math.max(0,255-Math.floor(512*s));let h=`rgba(${a}, ${c}, ${c}, ${s<.001?"0.1":"0.3"})`;n._containsObstacle&&(h="rgba(255, 0, 0, 0.3)"),n._offBoardConnectedCapacityMeshNodeIds?.length&&(h="rgba(255, 165, 0, 0.3)"),e.rects.push({center:n.center,width:n.width-.2,height:n.height-.2,layer:`z${n.availableZ.join(",")}`,fill:h,label:`${n.capacityMeshNodeId}\npf: ${s.toFixed(3)}, memPf: ${o.toFixed(3)}\nC#: ${r}\nxSame: ${i.numSameLayerCrossings}, xLC: ${i.numEntryExitLayerChanges}, xTransition: ${i.numTransitionPairCrossings}\nobCmid: ${n._offBoardConnectedCapacityMeshNodeIds?.join(",")}\nobs: ${n._containsObstacle?"yes":"no"}`})}if(Eh(t))for(const[n,s]of t.portPointMap){const o=t.assignedPortPoints.get(n),i=o?t.colorMap[o.connectionName]??"blue":"rgba(150, 150, 150, 0.5)";e.circles.push({center:{x:s.x,y:s.y},radius:.05,fill:i,layer:`z${s.z}`,label:[n,`conn: ${o?.connectionName}`,`cd: ${s.distToCentermostPortOnZ}`,`connects: ${s.connectionNodeIds.join(",")}`,`rootConn: ${o?.rootConnectionName}`].filter(Boolean).join("\n")})}const n=Eh(t)?t.connectionsWithResults:t.connectionResults;for(const s of n){if(!s.path)continue;const n=s.connection,o=t.colorMap[n.name]??"blue",i=[];for(const t of s.path)i.push({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId});for(let n=0;n<i.length-1;n++){const s=i[n],r=i[n+1],a=s.z===r.z,c=s.z;let h;h=a?0===c?void 0:"10 5":"3 3 10";const l=s.nodeId?t.nodeMap.get(s.nodeId):null;if(l&&Ch(s,r,l.center,l.width,l.height)){const t=Th(s,r,l.center,l.width,l.height);e.lines.push({points:[{x:s.x,y:s.y},{x:t.x,y:t.y}],strokeColor:o,strokeDash:h}),e.lines.push({points:[{x:t.x,y:t.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}else e.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}}if(Eh(t)&&!t.solved&&t.candidates&&t.candidates.length>0){const n=t.currentConnection,s=n?t.colorMap[n.connection.name]??"blue":"blue";if(n){const[o,i]=n.nodeIds,r=t.nodeMap.get(o),a=t.nodeMap.get(i),c=n.connection.pointsToConnect[0],h=n.connection.pointsToConnect[n.connection.pointsToConnect.length-1];if(r&&a){const t=c?{x:c.x,y:c.y}:r.center,o=h?{x:h.x,y:h.y}:a.center;e.lines.push({points:[t,o],strokeColor:Nn(s,.5),strokeDash:"5 5"}),e.points.push({x:t.x,y:t.y,color:s,label:[`Start: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.points.push({x:o.x,y:o.y,color:s,label:[`End: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.circles.push({center:o,radius:.08,stroke:s,label:`Goal: ${n.connection.name}`})}}const o=[...t.candidates].sort((t,e)=>t.f-e.f).slice(0,1);for(const i of o){const o=[];let r=i;for(;r;)o.unshift({x:r.point.x,y:r.point.y,z:r.z,lastMoveWasOffBoard:r.lastMoveWasOffBoard,nodeId:r.currentNodeId}),r=r.prevCandidate;for(let n=0;n<o.length-1;n++){const i=o[n],r=o[n+1],a=i.z===r.z,c=i.z;let h;h=r.lastMoveWasOffBoard?"2 2":a?0===c?void 0:"10 5":"3 3 10";const l=i.nodeId?t.nodeMap.get(i.nodeId):null,d=.02*i.z;if(l&&Ch(i,r,l.center,l.width,l.height)){const t=Th(i,r,l.center,l.width,l.height);e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:t.x+d,y:t.y+d}],strokeColor:Nn(s,.25),strokeDash:h}),e.lines.push({points:[{x:t.x+d,y:t.y+d},{x:r.x+d,y:r.y+d}],strokeColor:Nn(s,.25),strokeDash:h})}else e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:r.x+d,y:r.y+d}],strokeColor:Nn(s,.25),strokeDash:h})}if(o.length>=1){const r=o[o.length-1];let a=0,c=0,h=0,l=0,d=0,u=0;const p=t.nodeMap.get(i.prevCandidate?.currentNodeId);if(p&&i.prevCandidate&&i.portPoint&&n){const e=n.connection.name,s={x:i.prevCandidate.point.x,y:i.prevCandidate.point.y,z:i.prevCandidate.z,connectionName:e},o={x:i.portPoint.x,y:i.portPoint.y,z:i.portPoint.z,connectionName:e},r=t.buildNodeWithPortPointsForCrossing(p,[s,o]),f=Ms(r);h=f.numSameLayerCrossings,l=f.numTransitionPairCrossings,d=f.numEntryExitLayerChanges;const m=t.capacityMeshNodeMap.get(p.capacityMeshNodeId);m&&(c=t.JUMPER_PF_FN_ENABLED&&1===p.availableZ.length?Ih(m,h):bh(m,h,d,l),a=c**2*t.NODE_PF_FACTOR),u=i.prevCandidate.g>0?i.g-i.prevCandidate.g:i.g}if(!n)continue;const[f,m]=n.nodeIds,g=t.nodeMap.get(m),y=g?Math.sqrt((r.x-g.center.x)**2+(r.y-g.center.y)**2):0,x=t.avgNodePitch>0?y/t.avgNodePitch:0,v=x*t.BASE_CANDIDATE_COST,b=t.nodeMemoryPfMap.get(i.currentNodeId)??0,P=-Math.log(1-b)*t.MEMORY_PF_FACTOR;e.circles.push({center:r,radius:.03,fill:Nn(s,.25),layer:`z${i.z}`,label:[`f: ${i.f.toFixed(2)}`,`g: ${i.g.toFixed(2)} (nodeDelta: ${u.toFixed(2)})`,`h: ${i.h.toFixed(2)}`,` dist: ${y.toFixed(2)}`,` estHops: ${x.toFixed(1)}`,` estStepCost: ${v.toFixed(2)}`,` memRiskCost: ${P.toFixed(2)}`,`z: ${i.z}`,`node: ${i.currentNodeId}`,`Cost(Pf): ${a.toFixed(3)}`,`Pf: ${c.toFixed(3)}`,`xSame: ${h}, xTrans: ${l}, xLC: ${d}`,`routeOffBoard=${t.currentConnectionShouldRouteOffBoard}`,`offBoardTouched=${i.hasTouchedOffBoardNode??!1}`,`lastMoveWasOffBoard=${i.lastMoveWasOffBoard??!1}`].join("\n")})}}}return e}function Rh(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=yh(n),r=Math.min(Ih(t,i.numSameLayerCrossings),o);s+=Math.log(1-r)}return s}var Oh=class extends Ln{constructor(t){super(),this.input=t;const{simpleRouteJson:e,capacityMeshNodes:n,inputNodes:s,colorMap:o,nodeMemoryPfMap:i,hyperParameters:r,precomputedInitialParams:a,fixedRoutes:c}=t;if(this.input=structuredClone(t),this.MAX_ITERATIONS=1e8,this.simpleRouteJson=e,this.inputNodes=s,this.colorMap=o??{},this.capacityMeshNodeMap=new Map(n.map(t=>[t.capacityMeshNodeId,t])),this.nodeMemoryPfMap=i??new Map,this.hyperParameters=r??{},a){this.nodeMap=a.nodeMap,this.avgNodePitch=a.avgNodePitch,this.offBoardNodes=a.offBoardNodes,this.portPointMap=a.portPointMap,this.nodePortPointsMap=a.nodePortPointsMap,this.connectionNameToGoalNodeIds=a.connectionNameToGoalNodeIds;const{nodeAssignedPortPoints:t}=function(t){const e=new Map;for(const[n,s]of t.nodeAssignedPortPoints)e.set(n,[...s]);return{nodeAssignedPortPoints:e}}(a);this.nodeAssignedPortPoints=t,this.connectionsWithResults=Vn(structuredClone(a.unshuffledConnectionsWithResults),this.hyperParameters.SHUFFLE_SEED??0)}else{this.nodeMap=new Map(s.map(t=>[t.capacityMeshNodeId,t]));const t=s.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0);this.avgNodePitch=t.length>0?t.reduce((t,e)=>t+e,0)/t.length:1,this.offBoardNodes=s.filter(t=>t._offBoardConnectionId),this.portPointMap=new Map,this.nodePortPointsMap=new Map;for(const t of s)this.nodePortPointsMap.set(t.capacityMeshNodeId,[]),this.nodeAssignedPortPoints.set(t.capacityMeshNodeId,[]);for(const t of s)for(const e of t.portPoints){this.portPointMap.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=this.nodePortPointsMap.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{connectionsWithResults:e,connectionNameToGoalNodeIds:n}=this.getConnectionsWithNodes();this.connectionsWithResults=e,this.connectionNameToGoalNodeIds=n}if(c&&c.length>0)for(const t of c)if(this.connectionsWithResults.push(t),t.portPoints)for(const e of t.portPoints)e.portPointId&&this.assignedPortPoints.set(e.portPointId,{connectionName:e.connectionName,rootConnectionName:e.rootConnectionName});for(const t of this.connectionsWithResults)t.path?this.processedConnectionQueue.push(t):this.unprocessedConnectionQueue.push(t);this.totalConnectionCount=this.connectionsWithResults.length}getSolverName(){return"PortPointPathingSolver"}hyperParameters;simpleRouteJson;inputNodes;nodeMap;nodePortPointsMap;portPointMap;connectionsWithResults=[];failedConnection=null;assignedPortPoints=new Map;nodeAssignedPortPoints=new Map;PORT_POINT_REUSE_FACTOR=1e3;BASE_COST_FOR_NOT_GOING_OFF_BOARD=100;get NODE_PF_FACTOR(){return this.hyperParameters.NODE_PF_FACTOR??50}get RANDOM_WALK_DISTANCE(){return this.hyperParameters.RANDOM_WALK_DISTANCE??0}get MEMORY_PF_FACTOR(){return this.hyperParameters.MEMORY_PF_FACTOR??0}get CENTER_OFFSET_FOCUS_SHIFT(){return this.hyperParameters.CENTER_OFFSET_FOCUS_SHIFT??0}get RANDOM_COST_MAGNITUDE(){return this.hyperParameters.RANDOM_COST_MAGNITUDE??0}get BASE_CANDIDATE_COST(){return this.hyperParameters.BASE_CANDIDATE_COST??0}get NODE_PF_MAX_PENALTY(){return this.hyperParameters.NODE_PF_MAX_PENALTY??1e4}get FORCE_CENTER_FIRST(){return this.hyperParameters.FORCE_CENTER_FIRST??!0}get FORCE_OFF_BOARD_FREQUENCY(){return 0===this.offBoardNodes.length?0:this.hyperParameters.FORCE_OFF_BOARD_FREQUENCY??0}get FORCE_OFF_BOARD_SEED(){return this.hyperParameters.FORCE_OFF_BOARD_SEED??0}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.NODE_PF_MAX_PENALTY))}get CENTER_OFFSET_DIST_PENALTY_FACTOR(){return this.hyperParameters.CENTER_OFFSET_DIST_PENALTY_FACTOR??0}get STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR(){return this.hyperParameters.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR??0}colorMap;get GREEDY_MULTIPLIER(){return this.hyperParameters.GREEDY_MULTIPLIER??1.3}MAX_CANDIDATES_IN_MEMORY=5e3;get MAX_ITERATIONS_PER_PATH(){return this.hyperParameters.MAX_ITERATIONS_PER_PATH??1e4}ITERATIONS_PER_MM_FOR_PATH=30;BASE_ITERATIONS_PER_PATH=1e4;get RIPPING_ENABLED(){return this.hyperParameters.RIPPING_ENABLED??!1}get RIPPING_PF_THRESHOLD(){const t=this.hyperParameters.START_RIPPING_PF_THRESHOLD,e=this.hyperParameters.END_RIPPING_PF_THRESHOLD;if(void 0!==t&&void 0!==e){const n=this.MAX_RIPS;return t+(n>0?this.totalRipCount/n:0)*(e-t)}return this.hyperParameters.RIPPING_PF_THRESHOLD??.3}get MAX_RIPS(){return this.hyperParameters.MAX_RIPS??100}get RANDOM_RIP_FRACTION(){return this.hyperParameters.RANDOM_RIP_FRACTION??0}get JUMPER_PF_FN_ENABLED(){return this.hyperParameters.JUMPER_PF_FN_ENABLED??!1}jumpersPerMmSquared=.1;testedRipConnections=new Map;totalRipCount=0;get MIN_ALLOWED_BOARD_SCORE(){return this.hyperParameters.MIN_ALLOWED_BOARD_SCORE??-1e4}nodeMemoryPfMap;unprocessedConnectionQueue=[];processedConnectionQueue=[];currentConnection=null;totalConnectionCount=0;currentPathIterations=0;candidates;visitedPortPoints;connectionNameToGoalNodeIds;capacityMeshNodeMap;avgNodePitch;currentConnectionShouldRouteOffBoard=!1;activeCandidateStraightLineDistance;offBoardNodes=[];baseNodeCostCache=new Map;getConstructorParams(){return this.input}clearCostCaches(){this.baseNodeCostCache.clear()}clampPf(t){return Number.isFinite(t)?Math.min(Math.max(t,0),.999999):.999999}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseNodeFailureCost(t){const e=this.baseNodeCostCache.get(t);if(null!=e)return e;const n=this.nodeMap.get(t);if(!n)return 0;const s=this.computeNodePf(n),o=this.pfToFailureCost(s);return this.baseNodeCostCache.set(t,o),o}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.JUMPER_PF_FN_ENABLED?Rh(t,this.capacityMeshNodeMap):Ph(t,this.capacityMeshNodeMap)}getMaxIterationsForCurrentPath(){const t=this.activeCandidateStraightLineDistance??0;return Math.min(this.BASE_ITERATIONS_PER_PATH+this.ITERATIONS_PER_MM_FOR_PATH*t,this.MAX_ITERATIONS_PER_PATH)}getNodeDeltaFailureCostForSegment(t,e,n){const s=this.nodeMap.get(t);if(!s)return 0;const o=this.getBaseNodeFailureCost(t),i=this.computeNodePf(s,[e,n]),r=this.pfToFailureCost(i),a=Math.max(0,r-o);return i>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:a*this.NODE_PF_FACTOR}getConnectionsWithNodes(){const{unshuffledConnectionsWithResults:t,connectionNameToGoalNodeIds:e}=uh(this.simpleRouteJson,this.inputNodes);return{connectionsWithResults:Vn(t,this.hyperParameters.SHUFFLE_SEED??0),connectionNameToGoalNodeIds:e}}buildNodeWithPortPointsForCrossing(t,e){const n=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[],s=e?[...n,...e]:n;return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:s,availableZ:t.availableZ}}computeNodePf(t,e){if(t._containsTarget)return 0;const n=this.buildNodeWithPortPointsForCrossing(t,e),s=yh(n);return this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Ih(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings):bh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}getPortPointReusePenalty(t,e){const n=this.assignedPortPoints.get(t);return n?e===n.rootConnectionName?0:this.PORT_POINT_REUSE_FACTOR:0}getOtherNodeId(t,e){const[n,s]=t.connectionNodeIds;return n===e?s:s===e?n:null}computeG(t,e,n,s,o){const i=t.currentNodeId,r=t.point,a={x:r.x,y:r.y,z:t.z,connectionName:s,rootConnectionName:o},c={x:e.x,y:e.y,z:e.z,connectionName:s,rootConnectionName:o},h=this.getNodeDeltaFailureCostForSegment(i,a,c);return t.g+h}computeGToEndTarget(t,e,n,s){const o=t.currentNodeId,i={x:t.point.x,y:t.point.y,z:t.z,connectionName:n,rootConnectionName:s},r={x:e.x,y:e.y,z:t.z,connectionName:n,rootConnectionName:s},a=this.getNodeDeltaFailureCostForSegment(o,i,r);return t.g+a}computeDistanceToNearestOffBoardNode(t){if(0===this.offBoardNodes.length)return 1/0;let e=1/0;for(const n of this.offBoardNodes){const s=k(t,n.center);s<e&&(e=s)}return e}computeH(t,e,n,s,o,i){if(this.RANDOM_WALK_DISTANCE>0&&o<this.RANDOM_WALK_DISTANCE)return 0;if(this.currentConnectionShouldRouteOffBoard&&!i)return this.BASE_COST_FOR_NOT_GOING_OFF_BOARD+this.computeDistanceToNearestOffBoardNode(t);const r=this.nodeMap.get(n);if(!r)return 0;const a=k(t,r.center),c=this.avgNodePitch>0?a/this.avgNodePitch:0,h=this.clampPf(this.nodeMemoryPfMap.get(e)??0),l=this.pfToFailureCost(h)*this.MEMORY_PF_FACTOR,d=c*this.BASE_CANDIDATE_COST,u=this.CENTER_OFFSET_DIST_PENALTY_FACTOR*t.distToCentermostPortOnZ**2;let p=0;if(this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR>0&&this.currentConnection){const e=X(t,this.currentConnection.connection.pointsToConnect[0],this.currentConnection.connection.pointsToConnect[1]);p=this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR*e}return a+d+l+u+p}getVisitedPortPointKey(t,e){return this.currentConnectionShouldRouteOffBoard&&e?`${t}:touched_off_board`:t}getAvailableExitPortPoints(t,e){const n=this.currentConnection?.connection.rootConnectionName,s=this.nodePortPointsMap.get(t)??[],o=[];for(const t of s){const s=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(s))continue;const i=this.assignedPortPoints.get(t.portPointId);i&&i?.rootConnectionName!==n||o.push(t)}return o}getAvailableExitPortPointsWithOmissions(t,e,n){const s=this.nodePortPointsMap.get(t)??[],o=this.currentConnection?.connection.rootConnectionName,i=new Map;for(const e of s){const s=this.getVisitedPortPointKey(e.portPointId,n);if(this.visitedPortPoints?.has(s))continue;const o=this.getOtherNodeId(e,t);if(!o)continue;this.nodeMap.get(o);const r=`${o}|${e.z}`,a=i.get(r)??[];a.push(e),i.set(r,a)}const r=[];for(const[,t]of i){t.sort((t,e)=>t.distToCentermostPortOnZ-e.distToCentermostPortOnZ);const e=t[0];if(!e)continue;const n=this.assignedPortPoints.get(e.portPointId),s=n&&n.rootConnectionName===o;if(!n||s){r.push(e);continue}const i=[...t].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y),a=[];let c=[];for(const t of i){const e=this.assignedPortPoints.get(t.portPointId);!e||e.rootConnectionName===o?c.push(t):c.length>0&&(a.push(c),c=[])}c.length>0&&a.push(c);for(const t of a){const e=Math.floor(t.length/2);r.push(t[e])}}return r}getAvailableExitPortPointsForOffboardConnection(t,e){const n=this.nodeMap.get(t);if(!n)return[];const s=this.currentConnection?.connection.rootConnectionName,o=[];for(const i of n?._offBoardConnectedCapacityMeshNodeIds??[]){if(i===t)continue;if(!this.nodeMap.get(i))continue;const n=this.nodePortPointsMap.get(i)??[];for(const t of n){const n=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(n))continue;const r=this.assignedPortPoints.get(t.portPointId);r&&r.rootConnectionName!==s||o.push({...t,throughNodeId:i})}}return o}canTravelThroughObstacle(t,e,n){const s=this.connectionNameToGoalNodeIds.get(e);return s?.includes(t.capacityMeshNodeId)||Boolean(t._offBoardConnectionId)}isAtEndGoal(t,e){return t===e}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(n.lastMoveWasOffBoard&&n.throughNodeId){const t=this.nodeMap.get(n.throughNodeId),s=n.prevCandidate?this.nodeMap.get(n.prevCandidate.currentNodeId):null;e.push(n),t&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.throughNodeId,point:t.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0}),s&&s._offBoardConnectionId&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.prevCandidate.currentNodeId,point:s.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0})}else e.push(n);n=n.prevCandidate}return e.reverse()}assignPortPointsForPath(t,e,n){const s=[];for(let o=0;o<t.length;o++){const i=t[o];if(!i.portPoint){const r=0===o,a=o===t.length-1;if(!r&&!a){const t={x:i.point.x,y:i.point.y,z:i.z,connectionName:e,rootConnectionName:n};s.push(t);const o=this.nodeAssignedPortPoints.get(i.currentNodeId)??[];o.push(t),this.nodeAssignedPortPoints.set(i.currentNodeId,o)}continue}const r=i.portPoint;this.assignedPortPoints.set(r.portPointId,{connectionName:e,rootConnectionName:n});const a={portPointId:r.portPointId,x:r.x,y:r.y,z:r.z,connectionName:e,rootConnectionName:n};s.push(a);for(const t of r.connectionNodeIds){const e=this.nodeAssignedPortPoints.get(t)??[];e.push(a),this.nodeAssignedPortPoints.set(t,e)}}const o=Array.from(new Set(t.map(t=>t.currentNodeId)));for(const t of o){const s=this.nodeMap.get(t);if(s&&s._offBoardConnectionId)for(const t of s?._offBoardConnectedCapacityMeshNodeIds??[]){const s=this.nodePortPointsMap.get(t)??[];for(const t of s)this.assignedPortPoints.set(t.portPointId,{connectionName:e,rootConnectionName:n})}}return s}addTargetPointsToNodes(t,e){const n=t[0],s=t[t.length-1],o=e.pointsToConnect[0],i=e.pointsToConnect[e.pointsToConnect.length-1];if(n&&o){const t=this.nodeAssignedPortPoints.get(n.currentNodeId)??[];t.push({x:o.x,y:o.y,z:n.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(n.currentNodeId,t)}if(s&&i){const t=this.nodeAssignedPortPoints.get(s.currentNodeId)??[];t.push({x:i.x,y:i.y,z:s.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(s.currentNodeId,t)}}isPortPointInPathChain(t,e){let n=t;for(;n;){if(n.portPoint?.portPointId===e)return!0;n=n.prevCandidate}return!1}isNodeInPathChain(t,e){let n=t;for(;n;){if(n.currentNodeId===e)return!0;n=n.prevCandidate}return!1}_step(){if(this.currentConnection||(this.currentConnection=this.unprocessedConnectionQueue.shift()??null),!this.currentConnection){const t=this.computeBoardScore();return this.stats={boardScore:t,totalRipCount:this.totalRipCount},t<this.MIN_ALLOWED_BOARD_SCORE?(this.failedConnection=null,this.failed=!0,void(this.error=`Board score ${t.toFixed(2)} is less than MIN_ALLOWED_BOARD_SCORE ${this.MIN_ALLOWED_BOARD_SCORE.toFixed(2)}`)):void(this.solved=!0)}const t=this.currentConnection;this.activeCandidateStraightLineDistance=t.straightLineDistance,this.currentPathIterations++;const e=this.getMaxIterationsForCurrentPath();if(this.currentPathIterations>e)return this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,this.failed=!0,void(this.error=`Exceeded max iterations for path (${e}) on connection ${t.connection.name}`);const[n,s]=t.nodeIds,o=this.nodeMap.get(n),i=this.nodeMap.get(s);if(!o||!i)return this.processedConnectionQueue.push(t),this.currentConnection=null,void(this.currentPathIterations=0);const r=t.connection.name,a=t.connection.rootConnectionName,c=t.connection.pointsToConnect[0];if(!this.candidates){if(this.clearCostCaches(),this.FORCE_OFF_BOARD_FREQUENCY>0){const t=Hn(17*(this.hyperParameters.SHUFFLE_SEED??0)+this.FORCE_OFF_BOARD_SEED+this.processedConnectionQueue.length);this.currentConnectionShouldRouteOffBoard=t()<this.FORCE_OFF_BOARD_FREQUENCY}else this.currentConnectionShouldRouteOffBoard=!1;this.candidates=[],this.visitedPortPoints=new Set;for(const t of o.availableZ){const e=c?{x:c.x,y:c.y}:o.center,i=this.computeH({...e,distToCentermostPortOnZ:0},n,s,t,0,!1),r=0+i*this.GREEDY_MULTIPLIER;this.candidates.push({prevCandidate:null,portPoint:null,currentNodeId:n,point:e,z:t,f:r,g:0,h:i,distanceTraveled:0,hasTouchedOffBoardNode:!1})}}this.candidates.sort((t,e)=>t.f-e.f);let h,l=this.candidates.shift();for(;l?.portPoint&&this.visitedPortPoints;){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);if(!this.visitedPortPoints.has(t))break;l=this.candidates.shift()}if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!l)return this.error=`Ran out of candidates on connection ${r}`,this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,void(this.failed=!0);if(l.portPoint&&this.visitedPortPoints){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);this.visitedPortPoints.add(t)}if(this.isAtEndGoal(l.currentNodeId,s)){const e=t.connection.pointsToConnect[t.connection.pointsToConnect.length-1],n=e?{x:e.x,y:e.y}:i.center,o=this.computeGToEndTarget(l,n,r,a),c={prevCandidate:l,portPoint:null,currentNodeId:s,point:n,z:l.z,g:o,h:0,f:o,distanceTraveled:l.distanceTraveled+k(l.point,n)},h=this.getBacktrackedPath(c);return t.path=h,t.portPoints=this.assignPortPointsForPath(h,r,a),this.addTargetPointsToNodes(h,t.connection),this.clearCostCaches(),this.RIPPING_ENABLED&&this.processRippingForPath(h,r),this.processedConnectionQueue.push(t),this.currentConnection=null,this.progress=this.processedConnectionQueue.length/this.totalConnectionCount,this.candidates=null,this.visitedPortPoints=null,void(this.currentPathIterations=0)}const d=this.nodeMap.get(l.currentNodeId);h=d?._offBoardConnectionId?this.getAvailableExitPortPointsForOffboardConnection(l.currentNodeId,l.hasTouchedOffBoardNode):this.FORCE_CENTER_FIRST?this.getAvailableExitPortPointsWithOmissions(l.currentNodeId,s,l.hasTouchedOffBoardNode):this.getAvailableExitPortPoints(l.currentNodeId,l.hasTouchedOffBoardNode);for(const t of h){if(this.isPortPointInPathChain(l,t.portPointId))continue;if(this.visitedPortPoints?.has(t.portPointId))continue;const e=this.getOtherNodeId(t,t.throughNodeId??l.currentNodeId);if(!e)continue;if(this.isNodeInPathChain(l,e))continue;const n="throughNodeId"in t?t.throughNodeId:void 0,o=n?this.nodeMap.get(n):null,i=this.nodeMap.get(e);if(!i)continue;if(i._containsObstacle&&!this.canTravelThroughObstacle(i,r,a))continue;const c=this.computeG(l,t,e,r,a);if(!this.RIPPING_ENABLED&&c>-this.MIN_ALLOWED_BOARD_SCORE)continue;const h=l.distanceTraveled+k(l.point,t),u=l.hasTouchedOffBoardNode||Boolean(i._offBoardConnectionId),p=this.computeH(t,e,s,t.z,h,u),f=c+p*this.GREEDY_MULTIPLIER,m=Boolean(d?._offBoardConnectionId)&&Boolean(o?._offBoardConnectionId);this.candidates.push({prevCandidate:l,portPoint:t,currentNodeId:e,point:{x:t.x,y:t.y},z:t.z,f:f,g:c,h:p,distanceTraveled:h,lastMoveWasOffBoard:m,throughNodeId:m?n:void 0,hasTouchedOffBoardNode:u||Boolean(i._offBoardConnectionId)||Boolean(d?._offBoardConnectionId)})}}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}getConnectionsInNode(t,e){const n=[],s=new Set;for(const o of this.connectionsWithResults)if(o.path&&o.connection.name!==e&&!s.has(o.connection.name))for(const e of o.path)if(e.currentNodeId===t){n.push(o),s.add(o.connection.name);break}return n}computeNodePfWithoutConnection(t,e){if(t._containsTarget)return{pf:0,totalCrossings:0};const n=(this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[]).filter(t=>t.connectionName!==e),s={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=yh(s),i=o.numSameLayerCrossings+o.numEntryExitLayerChanges+o.numTransitionPairCrossings;return{pf:bh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings),totalCrossings:i}}computeNodeCrossings(t){if(t._containsTarget)return 0;const e=this.buildNodeWithPortPointsForCrossing(t),n=yh(e);return n.numSameLayerCrossings+n.numEntryExitLayerChanges+n.numTransitionPairCrossings}ripConnection(t){const e=t.connection.name;for(const[t,n]of this.assignedPortPoints.entries())n.connectionName===e&&this.assignedPortPoints.delete(t);for(const[t,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(t=>t.connectionName!==e);this.nodeAssignedPortPoints.set(t,s)}t.path=void 0,t.portPoints=void 0}requeueConnection(t){this.totalRipCount++;const e=this.processedConnectionQueue.indexOf(t);if(-1!==e)return this.processedConnectionQueue.splice(e,1),this.unprocessedConnectionQueue.push(t),!0;const n=this.unprocessedConnectionQueue.indexOf(t);return-1!==n&&(this.unprocessedConnectionQueue.splice(n,1),this.unprocessedConnectionQueue.unshift(t)),!0}processRippingForPath(t,e){const n=Array.from(new Set(t.map(t=>t.currentNodeId)));let s=!1;for(const t of n){if(this.totalRipCount>this.MAX_RIPS)break;const n=this.nodeMap.get(t);if(!n)continue;let o=this.computeNodePf(n);if(o<=this.RIPPING_PF_THRESHOLD)continue;this.testedRipConnections.has(t)||this.testedRipConnections.set(t,new Set);const i=this.testedRipConnections.get(t),r=Vn(this.getConnectionsInNode(t,e),(this.hyperParameters.SHUFFLE_SEED??0)+this.processedConnectionQueue.length);for(const t of r){if(o<=this.RIPPING_PF_THRESHOLD)break;const e=t.connection.name;i.add(e);const{pf:r}=this.computeNodePfWithoutConnection(n,e);this.ripConnection(t);if(!this.requeueConnection(t))return;o=r,s=!0,this.clearCostCaches()}}s&&this.RANDOM_RIP_FRACTION>0&&this.processRandomRipping(e)}processRandomRipping(t){const e=this.processedConnectionQueue.filter(e=>void 0!==e.path&&e.connection.name!==t);if(0===e.length)return;const n=Math.max(1,Math.floor(this.RANDOM_RIP_FRACTION*e.length)),s=Vn(e,(this.hyperParameters.SHUFFLE_SEED??0)+this.totalRipCount+this.processedConnectionQueue.length);for(let t=0;t<n&&t<s.length&&!(this.totalRipCount>this.MAX_RIPS);t++){const e=s[t];this.ripConnection(e);if(!this.requeueConnection(e))return;this.clearCostCaches()}}visualize(){let t={};if(this.failed){const e=this.failedConnection?.connection.pointsToConnect[0],n=this.failedConnection?.connection.pointsToConnect[1];e&&n&&(t={lines:[{points:[e,n],label:`Failed Connection ${this.failedConnection?.connection.name}`,strokeWidth:1,strokeColor:"red",strokeDash:[2,2]}]})}return M(wh(this),t)}},Ah=class extends os{getSolverName(){return"HyperPortPointPathingSolver"}params;precomputedInitialParams;constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e8,this.GREEDY_MULTIPLIER=1.2,this.MIN_SUBSTEPS=50,this.precomputedInitialParams=t.precomputedInitialParams??ph(t.simpleRouteJson,t.inputNodes)}getHyperParameterDefs(){const t=this.params.numShuffleSeeds??50;return[{name:"SHUFFLE_SEED",possibleValues:Array.from({length:t},(t,e)=>({SHUFFLE_SEED:e+1700*(this.params.hyperParameters?.SHUFFLE_SEED??0)}))}]}getCombinationDefs(){return[["SHUFFLE_SEED"]]}generateSolver(t){return new Oh({simpleRouteJson:this.params.simpleRouteJson,capacityMeshNodes:this.params.capacityMeshNodes,inputNodes:this.params.inputNodes,colorMap:this.params.colorMap,nodeMemoryPfMap:this.params.nodeMemoryPfMap,hyperParameters:{...this.params.hyperParameters,...t,MIN_ALLOWED_BOARD_SCORE:this.params.minAllowedBoardScore??t.MIN_ALLOWED_BOARD_SCORE??this.params.hyperParameters?.MIN_ALLOWED_BOARD_SCORE},precomputedInitialParams:this.precomputedInitialParams,fixedRoutes:this.params.fixedRoutes})}computeG(t){return-t.computeBoardScore()}computeH(t){const e=t.progress||0;if(e<.1)return 0;return-(t.computeBoardScore()/e)*(1-e)}getNodesWithPortPoints(){if(this.winningSolver)return this.winningSolver.getNodesWithPortPoints();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.getNodesWithPortPoints():[]}get connectionsWithResults(){if(this.winningSolver)return this.winningSolver.connectionsWithResults;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.connectionsWithResults:[]}get inputNodes(){if(this.winningSolver)return this.winningSolver.inputNodes;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.inputNodes:this.params.inputNodes}get nodeMap(){if(this.winningSolver)return this.winningSolver.nodeMap;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeMap:new Map(this.params.inputNodes.map(t=>[t.capacityMeshNodeId,t]))}get assignedPortPoints(){if(this.winningSolver)return this.winningSolver.assignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.assignedPortPoints:new Map}get nodeAssignedPortPoints(){if(this.winningSolver)return this.winningSolver.nodeAssignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeAssignedPortPoints:new Map}computeBoardScore(){if(this.winningSolver)return this.winningSolver.computeBoardScore();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.computeBoardScore():0}onSolve(t){this.stats={...t.solver.stats,winningHyperParameters:this.winningSolver?.hyperParameters}}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function zh(t){let e=t;return()=>{e+=1831565813;let t=e;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}var Lh=[{SHUFFLE_SEED:100,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,MEMORY_PF_FACTOR:0,EXPANSION_DEGREES:10,FORCE_CENTER_FIRST:!0,FORCE_OFF_BOARD_FREQUENCY:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0}],Dh=class extends Ln{getSolverName(){return"MultiSectionPortPointOptimizer"}simpleRouteJson;inputNodes;capacityMeshNodes;capacityMeshEdges;colorMap;nodeMap;capacityMeshNodeMap;connectionResults;assignedPortPoints;nodeAssignedPortPoints;sections=[];activeSubSolver=null;currentSection=null;sectionScoreBeforeOptimization=0;currentSectionCenterNodeId=null;currentScheduleIndex=0;nodePfMap=new Map;attemptsToFixNode=new Map;sectionAttempts=0;MAX_ATTEMPTS_PER_NODE=100;MAX_SECTION_ATTEMPTS=50;ACCEPTABLE_PF=.05;FRACTION_TO_REPLACE=.2;JUMPER_PF_FN_ENABLED=!1;SHUFFLE_SEEDS_PER_SECTION=null;ALWAYS_RIP_INTERSECTIONS=!0;effort=1;HYPERPARAMETER_SCHEDULE=Lh;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.simpleRouteJson=t.simpleRouteJson,this.inputNodes=t.inputNodes,this.capacityMeshNodes=t.capacityMeshNodes,this.capacityMeshEdges=t.capacityMeshEdges,this.colorMap=t.colorMap??{},this.effort=t.effort??1,void 0!==t.FRACTION_TO_REPLACE&&(this.FRACTION_TO_REPLACE=t.FRACTION_TO_REPLACE),void 0!==t.ALWAYS_RIP_INTERSECTIONS&&(this.ALWAYS_RIP_INTERSECTIONS=t.ALWAYS_RIP_INTERSECTIONS),void 0!==t.MAX_ATTEMPTS_PER_NODE&&(this.MAX_ATTEMPTS_PER_NODE=t.MAX_ATTEMPTS_PER_NODE),void 0!==t.MAX_SECTION_ATTEMPTS&&(this.MAX_SECTION_ATTEMPTS=t.MAX_SECTION_ATTEMPTS),void 0!==t.HYPERPARAMETER_SCHEDULE&&(this.HYPERPARAMETER_SCHEDULE=t.HYPERPARAMETER_SCHEDULE),this.JUMPER_PF_FN_ENABLED=t.JUMPER_PF_FN_ENABLED??this.JUMPER_PF_FN_ENABLED,this.SHUFFLE_SEEDS_PER_SECTION=t.SHUFFLE_SEEDS_PER_SECTION,this.MAX_SECTION_ATTEMPTS*=this.effort,this.nodeMap=new Map(t.inputNodes.map(t=>[t.capacityMeshNodeId,t])),this.capacityMeshNodeMap=new Map(t.capacityMeshNodes.map(t=>[t.capacityMeshNodeId,t])),this.connectionResults=[...t.initialConnectionResults],this.assignedPortPoints=new Map(t.initialAssignedPortPoints),this.nodeAssignedPortPoints=new Map(t.initialNodeAssignedPortPoints),this.nodePfMap=this.computeInitialPfMap();const e=this.computeBoardScore();this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.nodesExamined=0,this.stats.sectionAttempts=0,this.stats.sectionScores={},this.stats.initialBoardScore=e,this.stats.currentBoardScore=e,this.stats.errors=0}computeInitialPfMap(){const t=new Map;for(const e of this.capacityMeshNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];if(0===n.length)continue;const s={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===e.availableZ.length?Ih(e,yh(s).numSameLayerCrossings):Sh(s,e);t.set(e.capacityMeshNodeId,o)}return t}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.computeScoreForNodes(t)}computeScoreForNodes(t){return this.JUMPER_PF_FN_ENABLED?Rh(t,this.capacityMeshNodeMap):Ph(t,this.capacityMeshNodeMap)}recomputePfForNodes(t){for(const e of t){const t=this.capacityMeshNodeMap.get(e);if(!t)continue;const n=this.nodeAssignedPortPoints.get(e)??[];if(0===n.length){this.nodePfMap.set(e,0);continue}const s={capacityMeshNodeId:e,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Ih(t,yh(s).numSameLayerCrossings):Sh(s,t);this.nodePfMap.set(e,o)}}getCreatePortPointSectionInput(){return{inputNodes:this.inputNodes,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,nodeMap:this.nodeMap,connectionResults:this.connectionResults}}createSection(t){return function(t,e){const{inputNodes:n,capacityMeshNodes:s,capacityMeshEdges:o,connectionResults:i}=t,{centerOfSectionCapacityNodeId:r,expansionDegrees:a}=e,c=new Map;for(const t of o){const[e,n]=t.nodeIds;c.has(e)||c.set(e,new Set),c.has(n)||c.set(n,new Set),c.get(e).add(n),c.get(n).add(e)}const h=new Set,l=new Set,d=[];for(d.push({nodeId:r,depth:0}),l.add(r);d.length>0;){const{nodeId:t,depth:e}=d.shift();if(h.add(t),e<a){const n=c.get(t)??new Set;for(const t of n)l.has(t)||(l.add(t),d.push({nodeId:t,depth:e+1}))}}const u=n.filter(t=>h.has(t.capacityMeshNodeId)),p=s.filter(t=>h.has(t.capacityMeshNodeId)),f=[],m=[];for(const t of o){const[e,n]=t.nodeIds,s=h.has(e),o=h.has(n);s&&o?f.push(t):(s||o)&&m.push(t)}const g=u.map(t=>{const e=t.portPoints.filter(t=>{const[e,n]=t.connectionNodeIds,s=h.has(e),o=h.has(n);return s||o});return{...t,portPoints:e}}),y=function(t,e){const n=[];for(const s of t){if(!s.path||0===s.path.length)continue;const t=s.connection.name,o=s.connection.rootConnectionName,i=[];for(let t=0;t<s.path.length;t++){const n=s.path[t];e.has(n.currentNodeId)&&i.push(t)}if(0===i.length)continue;const r=i[0],a=i[i.length-1];let c=r,h=a;if(r>0){const t=s.path[0].currentNodeId;(s.nodeIds[0]===t||s.nodeIds[1]===t)&&(c=0)}if(a<s.path.length-1){const t=s.path.length-1,e=s.path[t].currentNodeId;(s.nodeIds[0]===e||s.nodeIds[1]===e)&&(h=t)}const l=s.path.slice(c,h+1),d=c>0,u=h<s.path.length-1;n.push({connectionName:t,rootConnectionName:o,points:l.map(t=>({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId,portPointId:t.portPoint?.portPointId})),originalStartIndex:c,originalEndIndex:h,hasEntryFromOutside:d,hasExitToOutside:u})}return n}(i??[],h);return{centerNodeId:r,expansionDegrees:a,nodeIds:h,inputNodes:g,capacityMeshNodes:p,internalEdges:f,boundaryEdges:m,sectionPaths:y}}(this.getCreatePortPointSectionInput(),t)}getSectionNodesWithPortPoints(t){const e=[];for(const n of t.nodeIds){const t=this.nodeMap.get(n),s=this.capacityMeshNodeMap.get(n);if(!t||!s)continue;const o=this.nodeAssignedPortPoints.get(n)??[];o.length>0&&e.push({capacityMeshNodeId:n,center:t.center,width:t.width,height:t.height,portPoints:o,availableZ:t.availableZ})}return e}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}findHighestPfNode(){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_ATTEMPTS_PER_NODE)**2>e&&(e=s,t=n)}return!t||e<this.ACCEPTABLE_PF?null:t}currentSectionCutPathInfo=new Map;currentSectionKeptPortPoints=new Map;currentSectionFixedRoutes=[];determineConnectionsToRip(t,e){const n=31337*this.sectionAttempts,s=zh(n);if(this.FRACTION_TO_REPLACE>=1)return new Set(e);const o=function(t,e){const n=zh(e),s=[...t];for(let t=s.length-1;t>0;t--){const e=Math.floor(n()*(t+1));[s[t],s[e]]=[s[e],s[t]]}return s}(e,n),i=Math.max(1,Math.ceil(o.length*this.FRACTION_TO_REPLACE)),r=new Set(o.slice(0,i));if(this.ALWAYS_RIP_INTERSECTIONS){const n=function(t){const{section:e,nodePfMap:n,capacityMeshNodeMap:s,nodeAssignedPortPoints:o,acceptablePf:i}=t,r=[];for(const t of e.nodeIds){if((n.get(t)??0)<=i)continue;const e=s.get(t);if(!e)continue;const a=o.get(t)??[];if(a.length<2)continue;const c=e.center.x-e.width/2,h=e.center.x+e.width/2,l=e.center.y-e.height/2,d=e.center.y+e.height/2,u=new Map;for(const t of a){const e=u.get(t.connectionName)??[];e.some(e=>e.x===t.x&&e.y===t.y&&e.z===t.z)||e.push({x:t.x,y:t.y,z:t.z}),u.set(t.connectionName,e)}const p=new Map;for(const[t,e]of u){if(e.length<2)continue;const n=e[0],s=e[1];if(n.z!==s.z)continue;const o=Mh(n,c,h,l,d),i=Mh(s,c,h,l,d),r=n.z,a=p.get(r)??[];a.push({connectionName:t,t1:o,t2:i}),p.set(r,a)}const f=1e-6;for(const[,t]of p){const e=t.map(t=>({connectionName:t.connectionName,a:Math.min(t.t1,t.t2),b:Math.max(t.t1,t.t2)}));for(let t=0;t<e.length;t++){const{connectionName:n,a:s,b:o}=e[t];for(let i=t+1;i<e.length;i++){const{connectionName:t,a:a,b:c}=e[i];Math.abs(s-a)<f||Math.abs(s-c)<f||Math.abs(o-a)<f||Math.abs(o-c)<f||(s<a&&a<o&&o<c||a<s&&s<c&&c<o)&&r.push([n,t])}}}}return r}({section:t,nodePfMap:this.nodePfMap,capacityMeshNodeMap:this.capacityMeshNodeMap,nodeAssignedPortPoints:this.nodeAssignedPortPoints,acceptablePf:this.ACCEPTABLE_PF});for(const[t,o]of n){if(r.has(t)||r.has(o))continue;const n=e.includes(t),i=e.includes(o);if(n&&i){const e=s()<.5;r.add(e?t:o)}else n?r.add(t):i&&r.add(o)}}return this.stats.lastRipCount=r.size,r}createSectionSimpleRouteJson(t){const e=[];this.currentSectionCutPathInfo.clear(),this.currentSectionKeptPortPoints.clear(),this.currentSectionFixedRoutes=[];const n=[],s=[];for(const e of this.connectionResults){if(!e.path||0===e.path.length)continue;const[o,i]=e.nodeIds,r=t.nodeIds.has(o),a=t.nodeIds.has(i);r&&a&&(s.push(e),n.push(e.connection.name))}const o=[];for(const e of t.sectionPaths){if(!e.hasEntryFromOutside&&!e.hasExitToOutside)continue;if(e.points.length<2)continue;const t=this.connectionResults.find(t=>t.connection.name===e.connectionName);t&&(o.push({sectionPath:e,originalResult:t}),n.includes(e.connectionName)||n.push(e.connectionName))}const i=this.determineConnectionsToRip(t,n);for(const t of s)i.has(t.connection.name)&&e.push(t.connection);for(const{sectionPath:t,originalResult:n}of o){if(!i.has(t.connectionName))continue;const s=`__cut__${t.connectionName}__${t.originalStartIndex}`;this.colorMap[s]=this.colorMap[t.connectionName];const o=t.points[0],r=t.points[t.points.length-1],a={name:s,rootConnectionName:t.rootConnectionName??t.connectionName,pointsToConnect:[{x:o.x,y:o.y,layers:[`layer${o.z+1}`]},{x:r.x,y:r.y,layers:[`layer${r.z+1}`]}]};e.push(a),this.currentSectionCutPathInfo.set(s,{sectionPath:t,originalConnectionResult:n})}const r=new Set(n.filter(t=>!i.has(t)));if(r.size>0){for(const e of t.nodeIds){const t=(this.nodeAssignedPortPoints.get(e)??[]).filter(t=>r.has(t.connectionName));t.length>0&&this.currentSectionKeptPortPoints.set(e,t)}for(const t of s)r.has(t.connection.name)&&this.currentSectionFixedRoutes.push(t);for(const{sectionPath:t,originalResult:e}of o)if(r.has(t.connectionName)){const n={connection:{name:t.connectionName,rootConnectionName:t.rootConnectionName,pointsToConnect:e.connection.pointsToConnect},path:t.points.map(t=>({prevCandidate:null,portPoint:null,currentNodeId:t.nodeId,point:{x:t.x,y:t.y},z:t.z,f:0,g:0,h:0,distanceTraveled:0})),portPoints:t.points.map(e=>({portPointId:e.portPointId,x:e.x,y:e.y,z:e.z,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName})),nodeIds:e.nodeIds,straightLineDistance:e.straightLineDistance};this.currentSectionFixedRoutes.push(n)}}return{...this.simpleRouteJson,connections:e}}prepareSectionInputNodesForCutPaths(t){const e=new Set;for(const[,t]of this.currentSectionCutPathInfo.entries()){const{sectionPath:n}=t;if(0===n.points.length)continue;const s=n.points[0].nodeId;e.add(s);const o=n.points[n.points.length-1].nodeId;e.add(o)}return t.inputNodes.map(t=>e.has(t.capacityMeshNodeId)?{...t,_containsTarget:!0}:t)}getHyperParametersForScheduleIndex(t,e){const n=this.HYPERPARAMETER_SCHEDULE[t];return{...n,SHUFFLE_SEED:(n.SHUFFLE_SEED??0)+17*e}}createSectionSolver(t){const e=this.createSectionSimpleRouteJson(t),n=this.prepareSectionInputNodesForCutPaths(t),s=ph(e,n);for(const[t,e]of this.currentSectionKeptPortPoints){const n=s.nodeAssignedPortPoints.get(t)??[];s.nodeAssignedPortPoints.set(t,[...n,...e])}return new Ah({simpleRouteJson:e,inputNodes:n,capacityMeshNodes:t.capacityMeshNodes,colorMap:this.colorMap,nodeMemoryPfMap:this.nodePfMap,numShuffleSeeds:this.SHUFFLE_SEEDS_PER_SECTION??2*e.connections.length*this.effort,hyperParameters:{...this.getHyperParametersForScheduleIndex(this.currentScheduleIndex,this.sectionAttempts)},precomputedInitialParams:s,fixedRoutes:this.currentSectionFixedRoutes})}reattachSection(t,e,n,s){const o=[],i=[];for(const t of e)t.connection.name.startsWith("__cut__")?i.push(t):o.push(t);const r=new Set(o.map(t=>t.connection.name));this.connectionResults=this.connectionResults.filter(t=>!r.has(t.connection.name)),this.connectionResults.push(...o);for(const[e,n]of this.nodeAssignedPortPoints.entries()){if(!t.nodeIds.has(e))continue;const s=n.filter(t=>!r.has(t.connectionName));this.nodeAssignedPortPoints.set(e,s)}for(const[t,e]of this.assignedPortPoints.entries())r.has(e.connectionName)&&this.assignedPortPoints.delete(t);for(const e of i){const n=this.currentSectionCutPathInfo.get(e.connection.name);if(!n||!e.path)continue;const{sectionPath:s,originalConnectionResult:o}=n,i=o.path;if(!i)continue;const r=s.connectionName;for(const[e,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(n=>n.connectionName!==r||!t.nodeIds.has(e));this.nodeAssignedPortPoints.set(e,s)}const a=i.slice(0,s.originalStartIndex),c=i.slice(s.originalEndIndex+1),h=[];let l=a.length>0?a[a.length-1]:null;for(const t of e.path){const e={...t,prevCandidate:l};h.push(e),l=e}if(c.length>0&&h.length>0&&(c[0]={...c[0],prevCandidate:h[h.length-1]}),o.path=[...a,...h,...c],e.portPoints)for(const n of e.portPoints){const e={...n,connectionName:r,rootConnectionName:s.rootConnectionName??r};for(const s of t.inputNodes)for(const t of s.portPoints)if(Math.abs(t.x-n.x)<.001&&Math.abs(t.y-n.y)<.001&&t.z===n.z){for(const n of t.connectionNodeIds){const t=this.nodeAssignedPortPoints.get(n)??[];t.push(e),this.nodeAssignedPortPoints.set(n,t)}break}}}for(const[t,e]of n.entries())e.connectionName.startsWith("__cut__")||this.assignedPortPoints.set(t,e);for(const[t,e]of s.entries()){const n=e.filter(t=>!t.connectionName.startsWith("__cut__"));if(n.length>0){const e=this.nodeAssignedPortPoints.get(t)??[];this.nodeAssignedPortPoints.set(t,[...e,...n])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved||this.activeSubSolver.failed){if(this.activeSubSolver.failed){if(this.currentScheduleIndex++,this.activeSubSolver.error&&this.stats.errors++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0;return}const t=this.activeSubSolver.getNodesWithPortPoints().map(t=>({...t,portPoints:t.portPoints.map(t=>{if(t.connectionName.startsWith("__cut__")){const e=t.connectionName.slice(7),n=e.lastIndexOf("__"),s=n>=0?e.slice(0,n):e;return{...t,connectionName:s}}return t})})),e=new Set;for(const n of t)for(const t of n.portPoints)e.add(t.connectionName);const n=this.getSectionNodesWithPortPoints(this.currentSection).map(t=>({...t,portPoints:t.portPoints.filter(t=>e.has(t.connectionName))})).filter(t=>t.portPoints.length>0),s=this.computeScoreForNodes(n),o=this.computeScoreForNodes(t),i=`attempt${this.sectionAttempts}`;if(this.stats.lastSectionScore=o,o>s){const t=this.stats.currentBoardScore;this.stats.lastBoardScore=t;const e=[...this.connectionResults],n=new Map(this.assignedPortPoints),s=new Map(Array.from(this.nodeAssignedPortPoints.entries()).map(([t,e])=>[t,[...e]]));this.reattachSection(this.currentSection,this.activeSubSolver.connectionsWithResults,this.activeSubSolver.assignedPortPoints,this.activeSubSolver.nodeAssignedPortPoints),this.recomputePfForNodes(this.currentSection.nodeIds);const o=this.computeBoardScore();this.stats.sectionScores[i]=o,o>t?(this.stats.successfulOptimizations++,this.stats.currentBoardScore=o):(this.connectionResults=e,this.assignedPortPoints=n,this.nodeAssignedPortPoints=s,this.recomputePfForNodes(this.currentSection.nodeIds),this.stats.failedOptimizations++),this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}else if(this.currentScheduleIndex++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}return}if(this.sectionAttempts>=this.MAX_SECTION_ATTEMPTS)return void(this.solved=!0);const t=this.findHighestPfNode();if(!t)return void(this.solved=!0);this.sectionAttempts++,this.stats.sectionAttempts=this.sectionAttempts,this.stats.nodesExamined++,this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.currentSectionCenterNodeId=t,this.currentScheduleIndex=0;const e=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:t,expansionDegrees:e.EXPANSION_DEGREES});const n=this.getSectionNodesWithPortPoints(this.currentSection);this.sectionScoreBeforeOptimization=this.computeScoreForNodes(n);if(0===this.createSectionSimpleRouteJson(this.currentSection).connections.length)return this.currentSection=null,void(this.currentSectionCenterNodeId=null);this.activeSubSolver=this.createSectionSolver(this.currentSection)}computeProgress(){return this.sectionAttempts/this.MAX_SECTION_ATTEMPTS}visualize(){return this.solved?wh(this):this.activeSubSolver?this.activeSubSolver.visualize():this.currentSection?function(t,e){const n={lines:[],points:[],rects:[],circles:[]};for(const e of t.inputNodes){const s=e.capacityMeshNodeId===t.centerNodeId,o=s?"rgba(0, 200, 0, 0.3)":"rgba(200, 200, 200, 0.3)";n.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,layer:`z${e.availableZ.join(",")}`,fill:o,label:`${e.capacityMeshNodeId}${s?" (CENTER)":""}`})}for(const e of t.inputNodes)for(const t of e.portPoints){const e="rgba(150, 150, 150, 0.5)";n.circles.push({center:{x:t.x,y:t.y},radius:.05,fill:e,layer:`z${t.z}`,label:[t.portPointId,`cd: ${t.distToCentermostPortOnZ}`,`connects: ${t.connectionNodeIds.join(",")}`].filter(Boolean).join("\n")})}for(const s of t.sectionPaths){const t=e?.[s.connectionName]??"blue";for(let e=0;e<s.points.length-1;e++){const o=s.points[e],i=s.points[e+1],r=o.z===i.z,a=o.z;let c;c=r?0===a?"5 5":"10 5":"3 3 10",n.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:t,strokeDash:c})}}return n}(this.currentSection,this.colorMap):wh(this)}},Fh=class{parent={};constructor(t){for(const e of t)this.parent[e]=e}find(t){return this.parent[t]===t?t:this.parent[t]=this.find(this.parent[t])}union(t,e){const n=this.find(t),s=this.find(e);n!==s&&(this.parent[s]=n)}getGroup(t){const e=this.find(t),n=[];for(const t in this.parent)this.find(t)===e&&n.push(t);return n}},Yh=class{point;left=null;right=null;constructor(t){this.point=t}},Xh=class{root=null;constructor(t){t.length>0&&(this.root=this.buildTree(t,0))}buildTree(t,e){const n=e%2==0?"x":"y";t.sort((t,e)=>t[n]-e[n]);const s=Math.floor(t.length/2),o=new Yh(t[s]);return s>0&&(o.left=this.buildTree(t.slice(0,s),e+1)),s<t.length-1&&(o.right=this.buildTree(t.slice(s+1),e+1)),o}findNearestNeighbor(t){if(!this.root)throw new Error("Tree is empty");const e=this.root.point,n=this.distance(t,e);return this.nearestNeighborSearch(this.root,t,0,e,n),e}nearestNeighborSearch(t,e,n,s,o){if(!t)return s;const i=n%2?"x":"y",r=this.distance(e,t.point);r<o&&(s=t.point,o=r);const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;return s=this.nearestNeighborSearch(c,e,n+1,s,o),o=this.distance(e,s),Math.abs(a)<o&&(s=this.nearestNeighborSearch(h,e,n+1,s,o)),s}findKNearestNeighbors(t,e){if(!this.root)return[];const n=[];return this.kNearestNeighborSearch(this.root,t,0,n,e),n.sort((t,e)=>t.distance-e.distance).slice(0,e).map(t=>t.point)}kNearestNeighborSearch(t,e,n,s,o){if(!t)return;const i=n%2?"x":"y",r=this.distance(e,t.point);s.push({point:t.point,distance:r});const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;this.kNearestNeighborSearch(c,e,n+1,s,o);let l=1/0;s.length>=o&&(s.sort((t,e)=>t.distance-e.distance),l=s[o-1]?.distance||1/0),(Math.abs(a)<l||s.length<o)&&this.kNearestNeighborSearch(h,e,n+1,s,o)}distance(t,e){return Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}},kh=class{parent=new Map;rank=new Map;constructor(t){for(const e of t){const t=this.pointToKey(e);this.parent.set(t,t),this.rank.set(t,0)}}pointToKey(t){return`${t.x},${t.y}`}find(t){const e=this.pointToKey(t);if(!this.parent.has(e))throw new Error(`Point ${e} not found in DisjointSet`);let n=e;for(;n!==this.parent.get(n);)n=this.parent.get(n);let s=e;for(;s!==n;){const t=this.parent.get(s);this.parent.set(s,n),s=t}return n}union(t,e){const n=this.find(t),s=this.find(e);if(n===s)return!1;const o=this.rank.get(n)||0,i=this.rank.get(s)||0;return o<i?this.parent.set(n,s):o>i?this.parent.set(s,n):(this.parent.set(s,n),this.rank.set(n,o+1)),!0}};function $h(t){if(t.length<=1)return[];const e=[...t],n=new Xh(e),s=[],o=Math.min(10,t.length-1);for(const t of e){const e=n.findKNearestNeighbors(t,o+1);for(const n of e){if(t.x===n.x&&t.y===n.y)continue;const e=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2);s.push({from:t,to:n,weight:e})}}s.sort((t,e)=>t.weight-e.weight);const i=new kh(e),r=[];for(const t of s)if(i.union(t.from,t.to)&&(r.push(t),r.length===e.length-1))break;return r}function Bh(t){if(t.pointId)return t.pointId;let e="";var n;return"layer"in(n=t)&&"string"==typeof n.layer?e=t.layer:_n(t)&&t.layers&&(e=t.layers.sort().join("-")),`${t.x.toFixed(4)},${t.y.toFixed(4)},${e}`}var jh=class extends Ln{constructor(t,e={}){super(),this.ogSrj=t,this.colorMap=e,this.unprocessedConnections=function(t){if(0===t.length)return[];const e=t.map((t,e)=>`conn_${e}`),n=new Fh(e),s=new Map;t.forEach((t,e)=>{const n=`conn_${e}`;t.pointsToConnect.forEach(t=>{const e=Bh(t);s.has(e)||s.set(e,[]),s.get(e).push(n)})});for(const t of s.values())if(t.length>1){const e=t[0];for(let s=1;s<t.length;s++)n.union(e,t[s])}const o=new Map;t.forEach((t,e)=>{const s=`conn_${e}`,i=n.find(s);o.has(i)||o.set(i,[]),o.get(i).push(t)});const i=[];for(const t of o.values()){if(1===t.length){i.push(t[0]);continue}const e=new Map,n=new Set;let s=!1;const o=[],r=new Set;let a;t.forEach(t=>{t.pointsToConnect.forEach(t=>e.set(Bh(t),t)),n.add(t.name),t.isOffBoard&&(s=!0),t.externallyConnectedPointIds&&o.push(...t.externallyConnectedPointIds),t.netConnectionName&&r.add(t.netConnectionName),void 0===a&&void 0!==t.nominalTraceWidth&&(a=t.nominalTraceWidth)});const c={name:Array.from(n).join("__"),mergedConnectionNames:Array.from(n),pointsToConnect:Array.from(e.values()),isOffBoard:s,externallyConnectedPointIds:o.length>0?o:void 0,netConnectionName:r.size>0?Array.from(r).join("__"):void 0,nominalTraceWidth:a};i.push(c)}return i}([...t.connections]),this.newConnections=[]}getSolverName(){return"NetToPointPairsSolver"}unprocessedConnections;newConnections;_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;return void this.newConnections.push({...t,rootConnectionName:t.name})}const o=$h(t.pointsToConnect);let i=0;for(const e of o)s(e.from,e.to)||this.newConnections.push({pointsToConnect:[e.from,e.to],name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}getNewSimpleRouteJson(){return{...structuredClone(this.ogSrj),connections:structuredClone(this.newConnections)}}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Net To Point Pairs Visualization"};return this.unprocessedConnections.forEach(e=>{e.pointsToConnect.forEach(n=>{t.points.push({x:n.x,y:n.y,color:"red",label:e.name})});const n=e.pointsToConnect.length**2,s=Hn(0),o=new Set;for(let i=0;i<Math.max(n,2*e.pointsToConnect.length);i++){const n=Math.floor(s()*e.pointsToConnect.length),i=Math.floor(s()*e.pointsToConnect.length);o.has(`${n}-${i}`)||(o.add(`${n}-${i}`),t.lines.push({points:[e.pointsToConnect[n],e.pointsToConnect[i]],strokeColor:"rgba(255,0,0,0.25)"}))}}),this.newConnections.forEach(e=>{const n=this.colorMap?.[e.name]||"blue";e.pointsToConnect.forEach(s=>{t.points.push({x:s.x,y:s.y,color:n,label:e.name})});for(let s=0;s<e.pointsToConnect.length-1;s++)for(let o=s+1;o<e.pointsToConnect.length;o++)t.lines.push({points:[e.pointsToConnect[s],e.pointsToConnect[o]],strokeColor:n})}),t}},Wh=class extends jh{constructor(t,e={}){const n=t.connections.flatMap(t=>t.pointsToConnect),s=new Map;for(const t of n)t.pointId&&s.set(t.pointId,t);const o=n.map(t=>t.pointId).filter(t=>!!t),i=new Fh(o),r=[];for(const e of t.connections)e.isOffBoard?e.pointsToConnect.length>=2&&e.pointsToConnect[0].pointId&&e.pointsToConnect[1].pointId&&i.union(e.pointsToConnect[0].pointId,e.pointsToConnect[1].pointId):r.push(e);super({...t,connections:r},e),this.ogSrj=t,this.colorMap=e,this.connectionPointDsu=i,this.connectionPointMap=s,this.ogSrj=t}getSolverName(){return"NetToPointPairsSolver2_OffBoardConnection"}connectionPointDsu;connectionPointMap;_findBestConnectionPointsFromDisjointSets(t,e){if(!t.pointId||!e.pointId)return{pointsToConnect:[t,e]};const n=this.connectionPointDsu.getGroup(t.pointId).map(t=>this.connectionPointMap.get(t)),s=this.connectionPointDsu.getGroup(e.pointId).map(t=>this.connectionPointMap.get(t));let o=t,i=e,r=1/0;for(const t of n)for(const e of s){const n=Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));n<r&&(r=n,o=t,i=e)}return{pointsToConnect:[o,i]}}_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;const e=this._findBestConnectionPointsFromDisjointSets(t.pointsToConnect[0],t.pointsToConnect[1]);return void this.newConnections.push({...t,pointsToConnect:e.pointsToConnect,rootConnectionName:t.name})}const o=$h(t.pointsToConnect);let i=0;for(const e of o){if(s(e.from,e.to))continue;const n=this._findBestConnectionPointsFromDisjointSets(e.from,e.to);this.newConnections.push({pointsToConnect:n.pointsToConnect,name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}}},Hh=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){const t=this.netMap[n],s=this.netMap[e];if(t&&s){t.push(...s),this.netMap[e]=t;for(const e of t)this.idToNetMap[e]=n}}}for(const t of e){const e=this.netMap[n];e&&!e.includes(t)&&e.push(t),this.idToNetMap[t]=n}}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){if(0===t.length)return!0;const e=this.getNetConnectedToId(t[0]);if(!e)return!1;for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}};function Uh(t,e={}){const n=[],s=[],o=e.color??"gray",i=e.label,r=En[t.footprint]??En["0603"],a=t.end.x-t.start.x,c=t.end.y-t.start.y,h=Math.abs(a)>Math.abs(c),l=h?r.padLength:r.padWidth,d=h?r.padWidth:r.padLength;return n.push({center:t.start,width:l,height:d,fill:Nn(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (start)`:void 0}),n.push({center:t.end,width:l,height:d,fill:Nn(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (end)`:void 0}),s.push({points:[t.start,t.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"}),{rects:n,lines:s}}function Vh(t,e={}){const n={rects:[],lines:[]};for(const s of t){const{rects:t,lines:o}=Uh(s,e);n.rects.push(...t),n.lines.push(...o)}return n}var Gh=1e5,Zh=.001,qh=class extends Ln{getSolverName(){return"SingleHighDensityRouteStitchSolver"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;constructor(t){if(super(),this.remainingHdRoutes=[...t.hdRoutes],this.colorMap=t.colorMap??{},0===t.hdRoutes.length){this.start=t.start,this.end=t.end;const e=[{x:t.start.x,y:t.start.y,z:t.start.z}],n=[];return t.start.z!==t.end.z&&(e.push({x:t.start.x,y:t.start.y,z:t.end.z}),n.push({x:t.start.x,y:t.start.y})),e.push({x:t.end.x,y:t.end.y,z:t.end.z}),this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:t.hdRoutes[0]?.rootConnectionName,route:e,vias:n,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:t.defaultTraceThickness??.15},void(this.solved=!0)}let e=1/0,n=t.hdRoutes[0],s="start-to-end";for(const o of t.hdRoutes){const i=o.route[0],r=o.route[o.route.length-1],a=k(t.start,i),c=k(t.start,r),h=k(t.end,i),l=k(t.end,r),d=Math.min(a,c,h,l);d<e&&(e=d,n=o,s=Math.min(h,l)<Math.min(a,c)?"end-to-start":"start-to-end")}"start-to-end"===s?(this.start=t.start,this.end=t.end):(this.start=t.end,this.end=t.start);const o=n.route[0],i=n.route[n.route.length-1],r=k(this.start,o)<=k(this.start,i)?o:i;this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:n.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:r.z}],vias:[],jumpers:[],viaDiameter:n.viaDiameter,traceThickness:n.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=>!this.remainingHdRoutes.some(n=>{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=>t.z===e.z&&k(e,t)<.001)})))return{firstRoute:t}}return{firstRoute:this.remainingHdRoutes[0]}}_step(){if(0===this.remainingHdRoutes.length){const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];return this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z}),void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n="first",s=1/0;for(let o=0;o<this.remainingHdRoutes.length;o++){const i=this.remainingHdRoutes[o],r=i.route[0],a=i.route[i.route.length-1],c=k(t,r),h=k(t,a);let l=1/0;l=t.z===r.z?c<Zh?c:Gh+c:c<Zh?1e3+c:Gh+c,l<s&&(s=l,e=o,n="first");let d=1/0;d=t.z===a.z?h<Zh?h:Gh+h:h<Zh?1e3+h:Gh+h,d<s&&(s=d,e=o,n="last")}if(-1===e)return void(this.remainingHdRoutes=[]);const o=this.remainingHdRoutes[e];let i;this.remainingHdRoutes.splice(e,1),i="first"===n?o.route:[...o.route].reverse(),i.length>0&&k(t,i[0])<Zh&&t.z===i[0].z?this.mergedHdRoute.route.push(...i.slice(1)):this.mergedHdRoute.route.push(...i),this.mergedHdRoute.vias.push(...o.vias),o.jumpers&&this.mergedHdRoute.jumpers.push(...o.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Single High Density Route Stitch Solver"};if(t.points?.push({x:this.start.x,y:this.start.y,color:"green",label:"Start"},{x:this.end.x,y:this.end.y,color:"red",label:"End"}),this.mergedHdRoute&&this.mergedHdRoute.route.length>1){t.lines?.push({points:this.mergedHdRoute.route.map(t=>({x:t.x,y:t.y})),strokeColor:"green"});for(const e of this.mergedHdRoute.route)t.points?.push({x:e.x,y:e.y,color:"green"});for(const e of this.mergedHdRoute.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:this.mergedHdRoute.viaDiameter/2,fill:"green"});if(this.mergedHdRoute.jumpers&&this.mergedHdRoute.jumpers.length>0){const e=Vh(this.mergedHdRoute.jumpers,{color:"green",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const[e,n]of this.remainingHdRoutes.entries()){const s=this.colorMap[n.connectionName]??"gray";n.route.length>1&&t.lines?.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:s});for(let o=0;o<n.route.length;o++){const i=n.route[o];t.points?.push({x:i.x+(e%2-.5)/500+(o%8-4)/1e3,y:i.y+(e%2-.5)/500+(o%8-4)/1e3,color:s,label:`Route ${n.connectionName} ${i===n.route[0]?"First":i===n.route[n.route.length-1]?"Last":""}`})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Vh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},Jh=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)},${Math.round(100*t.z)}`,Kh=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Hh({}),s=[],o=new Map;for(let e=0;e<t.hdRoutes.length;e++){const n=t.hdRoutes[e],o=n.route[0],i=n.route[n.route.length-1];s.push([`route_island_${e}`,`${n.connectionName}:${Jh(o)}`,`${n.connectionName}:${Jh(i)}`])}n.addConnections(s);for(const t of s)for(const e of t.slice(1))o.set(e,(o.get(e)??0)+1);this.unsolvedRoutes=[];const i=Array.from(new Set(Object.values(n.idToNetMap)));for(const e of i){const s=n.getIdsConnectedToNet(e),i=t.hdRoutes.filter((t,e)=>s.includes(`route_island_${e}`));if(0===i.length)continue;const r=t.connections.find(t=>t.name===i[0].connectionName),a=i.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),c=[];for(const t of a){const e=`${i[0].connectionName}:${Jh(t)}`;1===o.get(e)&&c.push(t)}if(0===c.length){console.log("no possible endpoints, can't stitch");continue}let h,l;2!==c.length?(h={...r.pointsToConnect[0],z:wn(Cn(r.pointsToConnect[0]),t.layerCount)},l={...r.pointsToConnect[1],z:wn(Cn(r.pointsToConnect[1]),t.layerCount)}):(h=c[0],l=c[1],k(h,r.pointsToConnect[1])<k(l,r.pointsToConnect[0])&&([h,l]=[l,h])),this.unsolvedRoutes.push({connectionName:i[0].connectionName,hdRoutes:i,start:h,end:l})}this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof qh&&this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute),this.activeSolver=null):this.activeSolver.failed&&(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new qh({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length&&t.points?.push(...e.points),e.lines?.length&&t.lines?.push(...e.lines),e.circles?.length&&t.circles?.push(...e.circles),e.rects?.length&&(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?Nn(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?Nn(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Vh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start (z=${e.start.z})`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End (z=${e.end.z})`}),t.lines?.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:n,strokeDash:"2 2"});for(const s of e.hdRoutes){s.route.length>1&&t.lines?.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:Nn(n,.5),strokeDash:"10 5"});for(const e of s.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:s.viaDiameter/2,fill:n});if(s.jumpers&&s.jumpers.length>0){const e=Vh(s.jumpers,{color:n,label:s.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},Qh=class{tree;constructor(t=9){this.tree=new st(t)}insert(t,e,n,s,o){this.tree.insert({minX:e,minY:n,maxX:s,maxY:o,data:t})}bulkLoad(t){const e=t.map(({item:t,minX:e,minY:n,maxX:s,maxY:o})=>({minX:e,minY:n,maxX:s,maxY:o,data:t}));this.tree.load(e)}search(t,e,n,s){return this.tree.search({minX:t,minY:e,maxX:n,maxY:s}).map(t=>t.data)}clear(){this.tree.clear()}},tl=class{index;items=[];currentIndex=0;capacity;constructor(t){this.capacity=Math.max(1,t),this.index=new E(this.capacity)}insert(t,e,n,s,o){if(this.currentIndex>=this.index.numItems)throw new Error("Exceeded initial capacity");this.items[this.currentIndex]=t,this.index.add(e,n,s,o),this.currentIndex++}finish(){this.index.finish()}search(t,e,n,s){return this.index.search(t,e,n,s).map(t=>this.items[t]||null).filter(Boolean)}clear(){this.items=[],this.currentIndex=0,this.index=new E(this.capacity)}},el=class{idx;storage=[];constructor(t="native",e=[]){"flatbush"===t?0===e.length?(this.idx=new Qh,t="rbush"):this.idx=new tl(e.length):this.idx="rbush"===t?new Qh:new class{shi=new nl(e);insert(t){}search(t,e,n,s){const o=(t+n)/2,i=(e+s)/2,r=n-t,a=s-e;return this.shi.getNodesInArea(o,i,r,a)}clear(){}},e.forEach(t=>this.insert(t)),"flatbush"===t&&e.length>0&&this.idx.finish?.()}insert(t){this.storage.push(t),this.idx.insert(t,t.center.x-t.width/2,t.center.y-t.height/2,t.center.x+t.width/2,t.center.y+t.height/2)}search(t){return this.idx.search(t.minX,t.minY,t.maxX,t.maxY)}searchArea(t,e,n,s){return this.search({minX:t-n/2,minY:e-s/2,maxX:t+n/2,maxY:e+s/2})}},nl=class{constructor(t){this.obstacles=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=n.center.x-n.width/2,o=n.center.y-n.height/2,i=n.center.x+n.width/2,r=n.center.y+n.height/2;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},sl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)});function ol(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function il(t,e,n){const s=ol(e,n);if(0===s)return ol(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return ol(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function rl(t,e,n,s){if(D(t,e,n,s))return 0;const o={x:t.x,y:t.y},i={x:e.x,y:e.y},r={x:n.x,y:n.y},a={x:s.x,y:s.y};return Math.min(il(o,r,a),il(i,r,a),il(r,o,i),il(a,o,i))}var al=class{segmentBuckets;viaBuckets;CELL_SIZE;constructor(t,e=1){this.segmentBuckets=new Map,this.viaBuckets=new Map,this.CELL_SIZE=e;for(const e of t)if(e&&e.connectionName){if(e.route&&e.route.length>=2)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],s=e.route[t+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=sl(o),r={segmentId:`${e.connectionName}-seg-${t}`,segment:o,parentRoute:e},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(e.vias&&e.vias.length>0)for(let t=0;t<e.vias.length;t++){const n=e.vias[t];if(null==n)continue;const s={viaId:`${e.connectionName}-via-${t}`,x:n.x,y:n.y,parentRoute:e},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}else console.warn("Skipping route with missing data:",e)}getConflictingRoutesForSegment(t,e,n){const s=sl([t,e]),o=s.minX-n,i=s.minY-n,r=s.maxX+n,a=s.maxY+n,c=Math.floor(o/this.CELL_SIZE),h=Math.floor((r+1e-9)/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor((a+1e-9)/this.CELL_SIZE),u=new Map,p=new Set,f=new Set,m={x:t.x,y:t.y},g={x:e.x,y:e.y};for(let s=c;s<=h;s++)for(let o=l;o<=d;o++){const i=`${s}x${o}`,r=this.segmentBuckets.get(i);if(r)for(const s of r){if(p.has(s.segmentId))continue;p.add(s.segmentId);const o=s.parentRoute,[i,r]=s.segment,a=n+o.traceThickness/2,c=a*a,h=rl(t,e,i,r);if(h<c){const t=o.connectionName,e=u.get(t);(!e||h<e.minDistSq)&&u.set(t,{route:o,minDistSq:h})}}const a=this.viaBuckets.get(i);if(a)for(const t of a){if(f.has(t.viaId))continue;f.add(t.viaId);const e=t.parentRoute,s={x:t.x,y:t.y},o=n+e.viaDiameter/2,i=o*o,r=il(s,m,g);if(r<i){const t=e.connectionName,n=u.get(t);(!n||r<n.minDistSq)&&u.set(t,{route:e,minDistSq:r})}}}const y=[];for(const t of u.values())y.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return y}removeRoute(t){for(const[e,n]of this.segmentBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.segmentBuckets.delete(e):s.length!==n.length&&this.segmentBuckets.set(e,s)}for(const[e,n]of this.viaBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.viaBuckets.delete(e):s.length!==n.length&&this.viaBuckets.set(e,s)}}addRoute(t){if(!t||!t.connectionName)return void console.warn("Skipping route with missing data:",t);if(t.route&&t.route.length>=2)for(let e=0;e<t.route.length-1;e++){const n=t.route[e],s=t.route[e+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=sl(o),r={segmentId:`${t.connectionName}-seg-${e}`,segment:o,parentRoute:t},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(t.vias&&t.vias.length>0)for(let e=0;e<t.vias.length;e++){const n=t.vias[e];if(null==n)continue;const s={viaId:`${t.connectionName}-via-${e}`,x:n.x,y:n.y,parentRoute:t},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}getConflictingRoutesNearPoint(t,e){const n=t.x-e,s=t.y-e,o=t.x+e,i=t.y+e,r=Math.floor(n/this.CELL_SIZE),a=Math.floor((o+1e-9)/this.CELL_SIZE),c=Math.floor(s/this.CELL_SIZE),h=Math.floor((i+1e-9)/this.CELL_SIZE),l=new Map,d=new Set,u=new Set;for(let n=r;n<=a;n++)for(let s=c;s<=h;s++){const o=`${n}x${s}`,i=this.segmentBuckets.get(o);if(i)for(const n of i){if(d.has(n.segmentId))continue;d.add(n.segmentId);const s=n.segment[0],o=n.segment[1];if(s.z!==o.z||s.z!==t.z)continue;const i=n.parentRoute,r={x:n.segment[0].x,y:n.segment[0].y},a={x:n.segment[1].x,y:n.segment[1].y},c=e+i.traceThickness/2,h=c*c,u=il(t,r,a);if(u<h){const t=i.connectionName,e=l.get(t);(!e||u<e.minDistSq)&&l.set(t,{route:i,minDistSq:u})}}const r=this.viaBuckets.get(o);if(r)for(const n of r){if(u.has(n.viaId))continue;u.add(n.viaId);const s=n.parentRoute,o={x:n.x,y:n.y},i=e+s.viaDiameter/2,r=i*i,a=ol(t,o);if(a<r){const t=s.connectionName,e=l.get(t);(!e||a<e.minDistSq)&&l.set(t,{route:s,minDistSq:a})}}}const p=[];for(const t of l.values())p.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return p}},cl=class extends Ln{getSolverName(){return"SingleRouteUselessViaRemovalSolver"}obstacleSHI;hdRouteSHI;unsimplifiedRoute;routeSections;currentSectionIndex;TRACE_THICKNESS=.15;OBSTACLE_MARGIN=.1;constructor(t){super(),this.currentSectionIndex=0,this.obstacleSHI=t.obstacleSHI,this.hdRouteSHI=t.hdRouteSHI,this.unsimplifiedRoute=t.unsimplifiedRoute,this.routeSections=this.breakRouteIntoSections(this.unsimplifiedRoute)}breakRouteIntoSections(t){const e=[],n=t.route;if(0===n.length)return[];let s={startIndex:0,endIndex:-1,z:n[0].z,points:[n[0]]};for(let t=1;t<n.length;t++)n[t].z===s.z?s.points.push(n[t]):(s.endIndex=t-1,e.push(s),s={startIndex:t,endIndex:-1,z:n[t].z,points:[n[t]]});return s.endIndex=n.length-1,e.push(s),e}_step(){if(this.currentSectionIndex>=this.routeSections.length)return void(this.solved=!0);if(0===this.currentSectionIndex&&this.routeSections.length>1){const t=this.routeSections[0],e=this.routeSections[1];if(t.z!==e.z){const n=e.z,s=t.points[0];if(this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n}))return t.z=n,t.points=t.points.map(t=>({...t,z:n})),void(this.currentSectionIndex=2)}return void this.currentSectionIndex++}if(this.currentSectionIndex===this.routeSections.length-1){if(this.routeSections.length>=2){const t=this.routeSections[this.routeSections.length-1],e=this.routeSections[this.routeSections.length-2];if(t.z!==e.z){const n=e.z,s=t.points[t.points.length-1];this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n})&&(t.z=n,t.points=t.points.map(t=>({...t,z:n})))}}return void(this.solved=!0)}const t=this.routeSections[this.currentSectionIndex-1],e=this.routeSections[this.currentSectionIndex],n=this.routeSections[this.currentSectionIndex+1];if(t.z!==n.z)return void this.currentSectionIndex++;const s=t.z;if(this.canSectionMoveToLayer({currentSection:e,targetZ:s}))return e.z=s,e.points=e.points.map(t=>({...t,z:s})),void(this.currentSectionIndex+=2);this.currentSectionIndex++}canEndpointConnectOnLayer(t,e,n){const s=this.obstacleSHI.searchArea(t,e,2,2).filter(n=>{if(!n.connectedTo?.includes(this.unsimplifiedRoute.connectionName))return!1;const s=n.width/2+.05,o=n.height/2+.05,i=Math.abs(t-n.center.x)<=s,r=Math.abs(e-n.center.y)<=o;return i&&r});return!(s.length>0)||s.some(t=>t.zLayers?.includes(n))}canSectionMoveToLayer({currentSection:t,targetZ:e}){for(let n=0;n<t.points.length-1;n++){const s={...t.points[n],z:e},o={...t.points[n+1],z:e},i=this.hdRouteSHI.getConflictingRoutesForSegment(s,o,this.TRACE_THICKNESS);for(const{conflictingRoute:t,distance:e}of i)if(t.connectionName!==this.unsimplifiedRoute.connectionName&&e<this.TRACE_THICKNESS+t.traceThickness)return!1;const r={centerX:(s.x+o.x)/2,centerY:(s.y+o.y)/2,width:Math.abs(s.x-o.x),height:Math.abs(s.y-o.y)},a=this.obstacleSHI.searchArea(r.centerX,r.centerY,r.width+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN),r.height+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN));for(const t of a){if(t.connectedTo?.includes(this.unsimplifiedRoute.connectionName))continue;if(t.zLayers?.includes(e)){if(Math.abs(s.x-t.center.x)<.01&&Math.abs(s.y-t.center.y)<.01||Math.abs(o.x-t.center.x)<.01&&Math.abs(o.y-t.center.y)<.01)continue}if(K(s,o,t)<this.TRACE_THICKNESS+this.OBSTACLE_MARGIN)return!1}}return!0}getConstructorParams(){return{obstacleSHI:this.obstacleSHI,hdRouteSHI:this.hdRouteSHI,unsimplifiedRoute:this.unsimplifiedRoute}}getOptimizedHdRoute(){const t=this.routeSections.flatMap(t=>t.points),e=[];for(let n=0;n<t.length-1;n++)t[n].z!==t[n+1].z&&e.push({x:t[n].x,y:t[n].y});return{connectionName:this.unsimplifiedRoute.connectionName,rootConnectionName:this.unsimplifiedRoute.rootConnectionName,route:t,traceThickness:this.unsimplifiedRoute.traceThickness,vias:e,viaDiameter:this.unsimplifiedRoute.viaDiameter,jumpers:this.unsimplifiedRoute.jumpers}}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Route Useless Via Removal Solver"};for(let e=0;e<this.routeSections.length;e++){const n=this.routeSections[e];t.lines.push({points:n.points,strokeWidth:this.TRACE_THICKNESS,strokeColor:e===this.currentSectionIndex?"orange":0===n.z?"red":"blue"})}return t}},hl=(t,e=2)=>{const n=Array.from({length:e},(t,e)=>e);return t.map(t=>{const s=t.zLayers??t.layers?.map(t=>wn(t,e))??n,o=Array.from(new Set(s.filter(t=>t>=0&&t<e)));return{...t,zLayers:o.length>0?o:n}})},ll=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:hl(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.optimizedHdRoutes=[],this.unprocessedRoutes=[...t.unsimplifiedHdRoutes],this.obstacleSHI=new el("flatbush",this.input.obstacles),this.hdRouteSHI=new al(this.unsimplifiedHdRoutes)}getSolverName(){return"UselessViaRemovalSolver"}unsimplifiedHdRoutes;optimizedHdRoutes;unprocessedRoutes;activeSubSolver=null;obstacleSHI=null;hdRouteSHI=null;_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.optimizedHdRoutes.push(this.activeSubSolver.getOptimizedHdRoute()),this.activeSubSolver=null):(this.activeSubSolver.failed||this.activeSubSolver.error)&&(this.error=this.activeSubSolver.error,this.failed=!0));const t=this.unprocessedRoutes.shift();t?this.activeSubSolver=new cl({hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,unsimplifiedRoute:t}):this.solved=!0}getOptimizedHdRoutes(){return this.optimizedHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Useless Via Removal Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.optimizedHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Vh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},dl=class extends Ln{getSolverName(){return"SingleSimplifiedPathSolver"}newRoute;newVias;headIndex=0;tailIndex=0;inputRoute;otherHdRoutes;obstacles;connMap;colorMap;outline;constructor(t){super(),this.inputRoute=t.inputRoute,this.otherHdRoutes=t.otherHdRoutes,this.obstacles=t.obstacles,this.connMap=t.connMap,this.colorMap=t.colorMap,this.outline=t.outline,this.newRoute=[this.inputRoute.route[0]],this.newVias=[]}getConstructorParams(){return{inputRoute:this.inputRoute,otherHdRoutes:this.otherHdRoutes,obstacles:this.obstacles,connMap:this.connMap.netMap,colorMap:this.colorMap,outline:this.outline}}get simplifiedRoute(){return{connectionName:this.inputRoute.connectionName,rootConnectionName:this.inputRoute.rootConnectionName,traceThickness:this.inputRoute.traceThickness,viaDiameter:this.inputRoute.viaDiameter,route:this.newRoute,vias:this.newVias,jumpers:this.inputRoute.jumpers}}isValidPath(t){throw new Error("Not implemented")}_step(){throw new Error("Not implemented")}getVisualsForNewRouteAndObstacles(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Simplified Path Solver"};for(let e=0;e<this.inputRoute.route.length-1;e++)t.lines.push({points:[{x:this.inputRoute.route[e].x,y:this.inputRoute.route[e].y},{x:this.inputRoute.route[e+1].x,y:this.inputRoute.route[e+1].y}],strokeColor:"rgba(255, 0, 0, 0.8)",strokeDash:1===this.inputRoute.route[e].z?"5, 5":void 0,layer:`z${this.inputRoute.route[e].z.toString()}`});for(let e=0;e<this.newRoute.length;e++)e<this.newRoute.length-1&&t.lines.push({points:[{x:this.newRoute[e].x,y:this.newRoute[e].y},{x:this.newRoute[e+1].x,y:this.newRoute[e+1].y}],strokeWidth:.15,strokeColor:"rgba(0, 255, 0, 0.8)",strokeDash:1===this.newRoute[e].z?[.4,.4]:void 0,layer:`z${this.newRoute[e].z.toString()}`}),t.points.push({x:this.newRoute[e].x,y:this.newRoute[e].y,color:"rgba(0, 255, 0, 0.8)",label:`z: ${this.newRoute[e].z}`,layer:`z${this.newRoute[e].z.toString()}`});for(const e of this.newVias)t.circles.push({center:e,radius:this.inputRoute.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)"});for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});for(const e of this.otherHdRoutes)for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:0===e.route[n].z?"rgba(255, 0, 255, 0.5)":1===e.route[n].z?"rgba(128, 0, 128, 0.5)":"rgba(0, 0, 255, 0.5)",layer:`z${e.route[n].z.toString()}`});if("filteredObstaclePathSegments"in this){const e=this.filteredObstaclePathSegments;for(const[n,s]of e)t.lines.push({points:[n,s]})}return t}};function ul(t,e,n,s){if(D(t,e,n,s))return 0;const o=pl(t,n,s),i=pl(e,n,s),r=pl(n,t,e),a=pl(s,t,e);return Math.min(o,i,r,a)}function pl(t,e,n){const s={x:n.x-e.x,y:n.y-e.y},o=fl({x:t.x-e.x,y:t.y-e.y},s);if(o<=0)return ml(t,e);const i=fl(s,s);if(i<=o)return ml(t,n);const r=o/i;return ml(t,{x:e.x+r*s.x,y:e.y+r*s.y})}function fl(t,e){return t.x*e.x+t.y*e.y}function ml(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var gl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)}),yl=class{constructor(t){this.segments=t,this.buckets=new Map;const e=new Map;for(const n of t){const t=this.getSegmentKey(n);if(e.has(t))continue;e.set(t,n);const s=gl(n),o=Math.floor(s.minX/this.CELL_SIZE),i=Math.floor(s.maxX/this.CELL_SIZE),r=Math.floor(s.minY/this.CELL_SIZE),a=Math.floor(s.maxY/this.CELL_SIZE);for(let e=o;e<=i;e++)for(let s=r;s<=a;s++){const o=`${e}x${s}`,i=this.buckets.get(o),r=[n[0],n[1],t];i?i.push(r):this.buckets.set(o,[r])}}}buckets;CELL_SIZE=.4;SEGMENT_MARGIN=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getSegmentKey(t){return`${t[0].x}-${t[0].y}-${t[0].z}-${t[1].x}-${t[1].y}-${t[1].z}`}getSegmentsThatCouldIntersect(t,e){const n=[],s=new Set,o=Math.min(t.x,e.x)-this.SEGMENT_MARGIN,i=Math.min(t.y,e.y)-this.SEGMENT_MARGIN,r=Math.max(t.x,e.x)+this.SEGMENT_MARGIN,a=Math.max(t.y,e.y)+this.SEGMENT_MARGIN,c=Math.floor(o/this.CELL_SIZE),h=Math.floor(r/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor(a/this.CELL_SIZE);for(let t=c;t<=h;t++)for(let e=l;e<=d;e++){const o=`${t}x${e}`,i=this.buckets.get(o);if(i)for(const t of i){const e=t[2];s.has(e)||(s.add(e),n.push(t))}}return n}},xl=1e-6,vl=(t,e,n)=>X(t,e,n)<=xl,bl=(t,e)=>Math.abs(t.x-e.x)<=xl&&Math.abs(t.y-e.y)<=xl,Pl=(t,e)=>{if(!e||e.length<3)return!1;for(let n=0;n<e.length;n++){const s=e[n],o=e[(n+1)%e.length];if(vl(t,s,o))return!0}let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s],r=e[o];i.y>t.y!=r.y>t.y&&t.x<(r.x-i.x)*(t.y-i.y)/(r.y-i.y)+i.x&&(n=!n)}return n},Sl=class extends dl{pathSegments=[];totalPathLength=0;headDistanceAlongPath=0;tailDistanceAlongPath=0;minStepSize=.25;lastValidPath=null;lastValidPathHeadDistance=0;STEP_SIZE_REDUCTION_FACTOR=.25;maxStepSize=4;currentStepSize=this.maxStepSize;lastHeadMoveDistance=0;cachedValidPathSegments;filteredObstacles=[];filteredObstaclePathSegments=[];filteredVias=[];filteredJumperPads=[];jumperPadPointIndices=new Set;segmentTree;OBSTACLE_MARGIN=.1;TRACE_THICKNESS=.15;TAIL_JUMP_RATIO=.8;constructor(t){if(super(t),this.cachedValidPathSegments=new Set,this.inputRoute.route.length<=1)return this.newRoute=[...this.inputRoute.route],void(this.solved=!0);const e=this.inputRoute.route.reduce((t,e)=>(t.minX=Math.min(t.minX,e.x),t.maxX=Math.max(t.maxX,e.x),t.minY=Math.min(t.minY,e.y),t.maxY=Math.max(t.maxY,e.y),t),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0}),n={center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY};this.filteredObstacles=this.obstacles.filter(t=>!t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t))).filter(t=>{if(t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t)))return!1;return function(t,e){const n=z(t),s=z(e),o=Math.max(n.minX-s.maxX,s.minX-n.maxX,0),i=Math.max(n.minY-s.maxY,s.minY-n.maxY,0);return Math.hypot(o,i)}(n,t)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2}),this.filteredObstaclePathSegments=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.route,s=[];for(let t=0;t<n.length-1;t++){const o=n[t],i=n[t+1],r=Math.min(o.x,i.x),a=Math.max(o.x,i.x),c=Math.min(o.y,i.y),h=Math.max(o.y,i.y);r<=e.maxX&&a>=e.minX&&c<=e.maxY&&h>=e.minY&&s.push([o,i])}return s}),this.segmentTree=new yl(this.filteredObstaclePathSegments),this.filteredVias=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.vias,s=[];for(const o of n){const n=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2+t.viaDiameter/2,i=o.x-n,r=o.x+n,a=o.y-n,c=o.y+n;i<=e.maxX&&r>=e.minX&&a<=e.maxY&&c>=e.minY&&s.push({...o,diameter:t.viaDiameter})}return s});const s=(t,n)=>{const s=[];for(const o of t){const t=En[o.footprint]??En["0603"],i=o.end.x-o.start.x,r=o.end.y-o.start.y,a=Math.abs(i)>Math.abs(r),c=a?t.padLength:t.padWidth,h=a?t.padWidth:t.padLength,l=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2;o.start.x-c/2-l<=e.maxX&&o.start.x+c/2+l>=e.minX&&o.start.y-h/2-l<=e.maxY&&o.start.y+h/2+l>=e.minY&&s.push({center:o.start,width:c,height:h,connectionName:n}),o.end.x-c/2-l<=e.maxX&&o.end.x+c/2+l>=e.minX&&o.end.y-h/2-l<=e.maxY&&o.end.y+h/2+l>=e.minY&&s.push({center:o.end,width:c,height:h,connectionName:n})}return s};if(this.filteredJumperPads=this.otherHdRoutes.flatMap(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName)?[]:s(t.jumpers??[],t.connectionName)),this.inputRoute.jumpers&&this.inputRoute.jumpers.length>0){this.filteredJumperPads.push(...s(this.inputRoute.jumpers,this.inputRoute.connectionName));for(const t of this.inputRoute.jumpers)for(let e=0;e<this.inputRoute.route.length;e++){const n=this.inputRoute.route[e];(Math.abs(n.x-t.start.x)<.01&&Math.abs(n.y-t.start.y)<.01||Math.abs(n.x-t.end.x)<.01&&Math.abs(n.y-t.end.y)<.01)&&this.jumperPadPointIndices.add(e)}}this.computePathSegments()}computePathSegments(){let t=0;for(let e=0;e<this.inputRoute.route.length-1;e++){const n=this.inputRoute.route[e],s=this.inputRoute.route[e+1],o=Math.sqrt((s.x-n.x)**2+(s.y-n.y)**2)+e/1e4;this.pathSegments.push({start:n,end:s,length:o,startDistance:t,endDistance:t+o}),t+=o}this.totalPathLength=t}arePointsEqual(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z}getPointAtDistance(t){t=Math.max(0,Math.min(t,this.totalPathLength));const e=this.pathSegments.find(e=>t>=e.startDistance&&t<=e.endDistance);if(!e)return this.inputRoute.route[this.inputRoute.route.length-1];const n=(t-e.startDistance)/e.length;return{x:e.start.x+n*(e.end.x-e.start.x),y:e.start.y+n*(e.end.y-e.start.y),z:n<.5?e.start.z:e.end.z}}getNearestIndexForDistance(t){if(t<=0)return 0;if(t>=this.totalPathLength)return this.inputRoute.route.length-1;const e=this.pathSegments.findIndex(e=>t>=e.startDistance&&t<=e.endDistance);if(-1===e)return 0;const n=this.pathSegments[e],s=(n.startDistance+n.endDistance)/2;return t>s?e+1:e}isValidPathSegment(t,e){for(const n of this.filteredObstacles){if(!n.zLayers?.includes(t.z))continue;if(K(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}const n=this.segmentTree.getSegmentsThatCouldIntersect(t,e);for(const[s,o,i]of n)if(s.z===t.z&&o.z===t.z){if(ul({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:o.x,y:o.y})<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS)return!1}for(const n of this.filteredVias)if(X(n,t,e)<this.OBSTACLE_MARGIN+n.diameter/2+this.TRACE_THICKNESS/2)return!1;for(const n of this.filteredJumperPads){if(K(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}if(this.outline&&this.outline.length>=3){const n=(({start:t,end:e,polygon:n,margin:s=.2})=>{if(!n||n.length<3)return!1;const o=Pl(t,n),i=Pl(e,n);if(!o||!i)return!0;for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length],a=vl(t,i,r),c=vl(e,i,r);if(a&&c)continue;if(!D(t,e,i,r)){if(!a&&!c&&ul(t,e,i,r)<s-xl)return!0;continue}const h=$(t,e,i,r);if(!(h&&(a&&bl(h,t)||c&&bl(h,e))||h&&(bl(h,t)||bl(h,e))))return!0}return!1})({start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},polygon:this.outline});if(n)return!1}return!0}isValidPath(t){if(t.length<2)return!0;for(let e=0;e<t.length-1;e++)if(t[e].z!==t[e+1].z)return!1;for(let e=0;e<t.length-1;e++)if(!this.isValidPathSegment(t[e],t[e+1]))return!1;return!0}find45DegreePath(t,e){if(this.arePointsEqual(t,e))return[t];if(t.z!==e.z)return null;const n=((t,e)=>{const n=[],s=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x>t.x?1:-1,r=e.y>t.y?1:-1,a={x:e.x-i*Math.abs(e.y-t.y),y:t.y};(a.x-t.x)*i>=0&&(a.x-e.x)*i<=0&&n.push([t,a,e]);const c={x:t.x,y:e.y-r*Math.abs(e.x-t.x)};(c.y-t.y)*r>=0&&(c.y-e.y)*r<=0&&n.push([t,c,e]);const h=Math.min(s,o),l={x:t.x+i*h,y:t.y+r*h};return(l.x-t.x)*i>=0&&(l.x-e.x)*i<=0&&(l.y-t.y)*r>=0&&(l.y-e.y)*r<=0&&n.push([t,l,e]),n})({x:t.x,y:t.y},{x:e.x,y:e.y});for(const e of n){const n=e.map(e=>({x:e.x,y:e.y,z:t.z}));if(this.isValidPath(n))return n}return null}addPathToResult(t){if(0!==t.length){for(let e=0;e<t.length;e++)0===e&&this.newRoute.length>0&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t[e])||this.newRoute.push(t[e]);this.currentStepSize=this.maxStepSize}}moveHead(t){this.lastHeadMoveDistance=t,this.headDistanceAlongPath=Math.min(this.headDistanceAlongPath+t,this.totalPathLength)}stepBackAndReduceStepSize(){this.headDistanceAlongPath=Math.max(this.tailDistanceAlongPath,this.headDistanceAlongPath-this.lastHeadMoveDistance),this.currentStepSize=Math.max(this.minStepSize,this.currentStepSize*this.STEP_SIZE_REDUCTION_FACTOR)}_step(){const t=this.tailDistanceAlongPath>=this.totalPathLength,e=this.headDistanceAlongPath>=this.totalPathLength;if(t){const t=this.inputRoute.route[this.inputRoute.route.length-1];return 0!==this.newRoute.length&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t)||this.newRoute.push(t),void(this.solved=!0)}if(e){const t=this.getPointAtDistance(this.tailDistanceAlongPath),e=this.inputRoute.route[this.inputRoute.route.length-1],n=this.find45DegreePath(t,e);if(n)return this.addPathToResult(n),void(this.solved=!0);this.lastValidPath=null,this.tailDistanceAlongPath=this.totalPathLength,this.headDistanceAlongPath=this.totalPathLength;const s=[];for(const t of this.inputRoute.route)0!==s.length&&this.arePointsEqual(s[s.length-1],t)||s.push(t);return this.newRoute=s,this.newVias=[...this.inputRoute.vias],void(this.solved=!0)}this.moveHead(this.currentStepSize);const n=this.getPointAtDistance(this.tailDistanceAlongPath),s=this.getPointAtDistance(this.headDistanceAlongPath),o=this.getNearestIndexForDistance(this.tailDistanceAlongPath),i=this.getNearestIndexForDistance(this.headDistanceAlongPath);let r=!1,a=-1;for(let t=o;t<i;t++)if(t+1<this.inputRoute.route.length&&this.inputRoute.route[t].z!==this.inputRoute.route[t+1].z){r=!0;const e=t;a=this.pathSegments[e].startDistance;break}if(r&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();let c=!1,h=-1,l=-1;for(let t=o+1;t<=i;t++)if(this.jumperPadPointIndices.has(t)){c=!0,h=t,l=t>0&&t-1<this.pathSegments.length?this.pathSegments[t-1].endDistance:this.pathSegments[0]?.startDistance??0;break}if(c&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();if(c&&h>=0){const t=this.inputRoute.route[h];this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const e=this.newRoute[this.newRoute.length-1];return e&&e.x===t.x&&e.y===t.y||this.newRoute.push({x:t.x,y:t.y,z:t.z}),this.currentStepSize=this.maxStepSize,this.tailDistanceAlongPath=l,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,void(this.lastValidPathHeadDistance=this.tailDistanceAlongPath)}if(r&&a>0){const t=this.getNearestIndexForDistance(a)+1,e=this.inputRoute.route[t],n={x:e.x,y:e.y};this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const s=this.newRoute[this.newRoute.length-1];s.x===n.x&&s.y===n.y||this.newRoute.push({x:n.x,y:n.y,z:s.z}),this.newVias.push(n),this.newRoute.push({x:n.x,y:n.y,z:e.z}),this.currentStepSize=this.maxStepSize;const o=this.pathSegments.findIndex(t=>t.start===e);if(-1!==o)this.tailDistanceAlongPath=this.pathSegments[o].startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath;else if(t<this.inputRoute.route.length){if(t===this.inputRoute.route.length-1)return void(this.solved=!0);console.warn("Fallback used for tailDistanceAlongPath after layer change");const e=this.pathSegments.find(e=>e.start===this.inputRoute.route[t]);e?(this.tailDistanceAlongPath=e.startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath):(console.error(`[${this.inputRoute.connectionName}] Could not find segment start after layer change. Path might be incomplete.\n Index sought: ${t}, Point: (${this.inputRoute.route[t].x.toFixed(3)}, ${this.inputRoute.route[t].y.toFixed(3)}, z=${this.inputRoute.route[t].z})\n Route Length: ${this.inputRoute.route.length}, Path Segments: ${this.pathSegments.length}`),this.solved=!0)}else console.warn("Layer change occurred at the end of the path."),this.solved=!0;return}const d=this.find45DegreePath(n,s);if(!d&&this.lastHeadMoveDistance>this.minStepSize)this.stepBackAndReduceStepSize();else{if(!d&&!this.lastValidPath){const t=this.getPointAtDistance(this.tailDistanceAlongPath);this.tailDistanceAlongPath+=this.minStepSize,this.moveHead(this.minStepSize);const e=this.getNearestIndexForDistance(this.tailDistanceAlongPath),n=this.inputRoute.route[e],s=this.inputRoute.route[this.inputRoute.route.length-1];return void(this.arePointsEqual(t,n)||this.arePointsEqual(n,s)||this.newRoute.push(n))}if(d)return this.lastValidPath=d,void(this.lastValidPathHeadDistance=this.headDistanceAlongPath);this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null,this.tailDistanceAlongPath=this.lastValidPathHeadDistance,this.moveHead(this.minStepSize))}}visualize(){const t=this.getVisualsForNewRouteAndObstacles(),e=this.getPointAtDistance(this.tailDistanceAlongPath),n=this.getPointAtDistance(this.headDistanceAlongPath);t.points.push({x:e.x,y:e.y,color:"yellow",label:["Tail",`z: ${e.z}`].join("\n")}),t.points.push({x:n.x,y:n.y,color:"orange",label:["Head",`z: ${n.z}`].join("\n")});const s=this.getPointAtDistance(this.headDistanceAlongPath+this.currentStepSize);t.points.push({x:s.x,y:s.y,color:"red",label:["Tentative Head",`z: ${s.z}`].join("\n")});let o=0;for(;o<this.totalPathLength;){const e=this.getPointAtDistance(o);t.circles.push({center:{x:e.x,y:e.y},radius:.05,fill:"rgba(100, 100, 100, 0.5)"}),o+=this.totalPathLength/20}if(this.lastValidPath&&this.lastValidPath.length>1)for(let e=0;e<this.lastValidPath.length-1;e++)t.lines.push({points:[{x:this.lastValidPath[e].x,y:this.lastValidPath[e].y},{x:this.lastValidPath[e+1].x,y:this.lastValidPath[e+1].y}],strokeColor:"rgba(0, 255, 255, 0.9)",strokeDash:"3, 3"});return t}},Ml=class extends Ln{getSolverName(){return"MultiSimplifiedPathSolver"}simplifiedHdRoutes;currentUnsimplifiedHdRouteIndex=0;activeSubSolver=null;unsimplifiedHdRoutes;obstacles;connMap;colorMap;outline;defaultViaDiameter;constructor(t){super(),this.MAX_ITERATIONS=1e8,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes;const e=Math.max(2,...t.unsimplifiedHdRoutes.flatMap(t=>t.route.map(t=>t.z+1)))||2;this.obstacles=hl(t.obstacles,e),this.connMap=t.connMap||new On({}),this.colorMap=t.colorMap||{},this.outline=t.outline,this.defaultViaDiameter=t.defaultViaDiameter??.3,this.simplifiedHdRoutes=[]}_step(){const t=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];if(!this.activeSubSolver)return t?(this.activeSubSolver=new Sl({inputRoute:t,otherHdRoutes:this.unsimplifiedHdRoutes.slice(this.currentUnsimplifiedHdRouteIndex+1).concat(this.simplifiedHdRoutes),obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline}),void this.currentUnsimplifiedHdRouteIndex++):void(this.solved=!0);this.activeSubSolver.step(),this.activeSubSolver.solved&&(this.simplifiedHdRoutes.push(this.activeSubSolver.simplifiedRoute),this.activeSubSolver=null)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Multi Simplified Path Solver"};for(const e of this.unsimplifiedHdRoutes)if(!this.simplifiedHdRoutes.some(t=>t.connectionName===e.connectionName)){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeColor:1===e.route[n].z?"rgba(0, 0, 255, 0.4)":"rgba(255, 0, 0, 0.4)",strokeWidth:.15,strokeDash:1===e.route[n].z?[.5,.5]:void 0});for(const n of e.vias||[])t.circles.push({center:n,radius:(e.viaDiameter??this.defaultViaDiameter)/2,fill:"rgba(0, 0, 255, 0.4)"})}for(const e of this.simplifiedHdRoutes){const n=this.colorMap?.[e.connectionName]||"rgba(128, 128, 128, 0.8)";for(let s=0;s<e.route.length-1;s++)t.lines.push({points:[{x:e.route[s].x,y:e.route[s].y},{x:e.route[s+1].x,y:e.route[s+1].y}],strokeWidth:.15,strokeColor:n,strokeDash:1===e.route[s].z?[.5,.5]:void 0,step:1});for(const n of e.vias||[])t.circles.push({center:n,radius:e.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)",step:1})}for(const e of this.unsimplifiedHdRoutes){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:"rgba(255, 0, 0, 0.2)",strokeDash:[.5,.5],step:0,layer:`z${e.route[n].z.toString()}`});for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 0, 0.2)",step:0})}for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});if(this.currentUnsimplifiedHdRouteIndex<this.unsimplifiedHdRoutes.length){const e=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];e.route.length>0&&t.circles.push({center:{x:e.route[0].x,y:e.route[0].y},radius:.2,fill:"yellow",label:"Current"})}return t}},Nl=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:hl(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.inputHdRoutes=this.input.inputHdRoutes,this.mergedViaHdRoutes=structuredClone(this.inputHdRoutes),this.unprocessedRoutes=[...this.input.inputHdRoutes],this.colorMap=this.input.colorMap,this.outline=this.input.outline,this.obstacles=this.input.obstacles,this.obstacleSHI=new el("flatbush",this.input.obstacles),this.hdRouteSHI=new al(this.inputHdRoutes),this.vias=[],this.offendingVias=[],this.connMap=t.connMap,this.viasByNet=new Map,this.rebuildVias()}getSolverName(){return"SameNetViaMergerSolver"}inputHdRoutes;mergedViaHdRoutes;unprocessedRoutes;vias;offendingVias;currentViaRoutes=[];connMap;colorMap;outline;obstacles;viasByNet;obstacleSHI=null;hdRouteSHI=null;rebuildVias(){this.vias=[],this.viasByNet=new Map;for(let t=0;t<this.mergedViaHdRoutes.length;t++){const e=this.mergedViaHdRoutes[t];for(let n=0;n<e.vias.length;n++){const s=e.vias[n],o={x:s.x,y:s.y,diameter:e.viaDiameter,net:this.connMap?.idToNetMap[e.connectionName]??"",layers:[...new Set(e.route.map(t=>t.z))],routeIndex:t};this.vias.push(o);const i=this.viasByNet.get(o.net);i?i.push(o):this.viasByNet.set(o.net,[o])}}}findNextOffendingPair(){for(let t=0;t<this.vias.length-1;t++){const e=this.vias[t],n=this.viasByNet.get(e.net);if(!n)continue;const s=n.indexOf(e);for(let t=s>=0?s+1:0;t<n.length;t++){const s=n[t],o=e.x-s.x,i=e.y-s.y,r=o*o+i*i,a=e.diameter/2+s.diameter/2;if(r<=a*a&&0!==r)return[e,s]}}return null}handleOffendingPair(t,e){const n=t.layers.length<e.layers.length?t:e,s=n===t?e:t,o=this.mergedViaHdRoutes[n.routeIndex].route;for(let t=0;t<n.layers.length;t++)for(let t=o.length-1;t>=1;t--){const e=o[t-1],i=o[t];if(i.x===n.x&&i.y===n.y){o.splice(t,0,{x:s.x,y:s.y,z:i.z}),o.splice(t,0,{x:s.x,y:s.y,z:e.z});const r=this.mergedViaHdRoutes[n.routeIndex];return r.vias=r.vias.map(t=>t.x===n.x&&t.y===n.y?{x:s.x,y:s.y}:t),void this.rebuildVias()}}this.rebuildVias()}_step(){const t=this.findNextOffendingPair();t?this.handleOffendingPair(t[0],t[1]):this.solved=!0}getMergedViaHdRoutes(){return this.mergedViaHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Same Net Via Merger Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.mergedViaHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"rgba(255, 0, 0, 0.5)":"rgba(0, 0, 255, 0.5)",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Vh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},Il=class extends Ln{constructor(t){super(),this.simplificationConfig=t,this.simplificationConfig={...t,obstacles:hl(t.obstacles,t.layerCount)},this.hdRoutes=[...t.hdRoutes],this.MAX_ITERATIONS=1e8}getSolverName(){return"TraceSimplificationSolver"}hdRoutes=[];simplificationPipelineLoops=0;MAX_SIMPLIFICATION_PIPELINE_LOOPS=2;PHASE_ORDER=["via_removal","via_merging","path_simplification"];currentPhase="via_removal";extractResult=null;get simplifiedHdRoutes(){return this.hdRoutes}_step(){if(this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)this.solved=!0;else{if(this.activeSubSolver){if(this.activeSubSolver.step(),!this.activeSubSolver.failed&&!this.activeSubSolver.solved)return;if(this.activeSubSolver.solved){if(this.extractResult&&(this.hdRoutes=this.extractResult(this.activeSubSolver)),this.activeSubSolver=null,this.extractResult=null,"via_removal"===this.currentPhase?this.currentPhase="via_merging":"via_merging"===this.currentPhase?this.currentPhase="path_simplification":(this.currentPhase="via_removal",this.simplificationPipelineLoops++),this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)return void(this.solved=!0)}else if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error??"Sub-solver failed without error message")}if(!this.activeSubSolver&&!this.solved)switch(this.currentPhase){case"via_removal":this.activeSubSolver=new ll({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount}),this.extractResult=t=>t.getOptimizedHdRoutes()??[];break;case"via_merging":this.activeSubSolver=new Nl({inputHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount,connMap:this.simplificationConfig.connMap,outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0}),this.extractResult=t=>t.getMergedViaHdRoutes()??[];break;case"path_simplification":this.activeSubSolver=new Ml({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,colorMap:{...this.simplificationConfig.colorMap},outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,defaultViaDiameter:this.simplificationConfig.defaultViaDiameter}),this.extractResult=t=>t.simplifiedHdRoutes;break;default:this.failed=!0,this.error=`Unknown phase: ${this.currentPhase}`}}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Trace Simplification Solver"};for(const e of this.simplificationConfig.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.hdRoutes)if(0!==e.route.length){for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Vh(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},_l=class extends Ln{getSolverName(){return"TraceWidthSolver"}hdRoutes;hdRoutesWithWidths=[];nominalTraceWidth;minTraceWidth;obstacleMargin;TRACE_WIDTH_SCHEDULE;connectionNominalTraceWidthMap;unprocessedRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;currentScheduleIndex=0;currentTargetWidth=0;hasInsufficientClearance=!1;lastCollidingObstacles=[];lastCollidingRoutes=[];lastClearance=1/0;obstacles=[];obstacleSHI;hdRouteSHI;connMap;colorMap;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.hdRoutes=[...t.hdRoutes],this.minTraceWidth=t.minTraceWidth,this.obstacleMargin=t.obstacleMargin??.15,this.nominalTraceWidth=0,this.TRACE_WIDTH_SCHEDULE=[],this.unprocessedRoutes=[...this.hdRoutes],this.connMap=t.connMap,this.colorMap=t.colorMap;const e=t.layerCount;this.obstacles=hl(t.obstacles??[],e),this.connectionNominalTraceWidthMap=new Map;for(const e of t.connection)void 0!==e.nominalTraceWidth&&this.connectionNominalTraceWidthMap.set(e.name,e.nominalTraceWidth);this.obstacles.length>0&&(this.obstacleSHI=new el("flatbush",this.obstacles)),this.hdRouteSHI=new al(this.hdRoutes)}getNominalTraceWidthForRoute(t){const e=this.connectionNominalTraceWidthMap.get(t.connectionName);return void 0!==e?e:t.rootConnectionName?this.connectionNominalTraceWidthMap.get(t.rootConnectionName):void 0}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.hdRoutesWithWidths=this.processedRoutes,void(this.solved=!0);const e=this.getNominalTraceWidthForRoute(t);if(void 0===e)return this.processedRoutes.push({...t}),void(this.currentTrace=null);this.currentTrace=t,this.nominalTraceWidth=e;const n=(this.nominalTraceWidth+this.minTraceWidth)/2;return this.TRACE_WIDTH_SCHEDULE=[this.nominalTraceWidth,n],this.currentTrace.route.length<2?(this.processedRoutes.push({...this.currentTrace,traceThickness:this.minTraceWidth}),void(this.currentTrace=null)):(this.currentScheduleIndex=0,this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[0],void this.initializeCursor())}if(!this.stepCursorForward())return void this.finalizeCurrentTrace(this.currentTargetWidth);this.getClearanceAtPosition(this.cursorPosition)<this.currentTargetWidth/2+this.obstacleMargin&&(this.hasInsufficientClearance=!0,this.currentScheduleIndex++,this.currentScheduleIndex<this.TRACE_WIDTH_SCHEDULE.length?(this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[this.currentScheduleIndex],this.initializeCursor()):this.finalizeCurrentTrace(this.minTraceWidth))}initializeCursor(){if(!this.currentTrace)return;const t=this.currentTrace.route[0];this.cursorPosition={...t},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,this.hasInsufficientClearance=!1}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return!1;const t=this.currentTrace.route;let e=.1;for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return!1;const n=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1];if(n.insideJumperPad&&s.insideJumperPad){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const o=s.x-n.x,i=s.y-n.y,r=Math.sqrt(o*o+i*i);if(0===r){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const a=this.currentTraceSegmentT*r,c=r-a;if(e<=c){const t=a+e;return this.currentTraceSegmentT=t/r,this.cursorPosition={x:n.x+o*this.currentTraceSegmentT,y:n.y+i*this.currentTraceSegmentT,z:n.z},!0}if(e-=c,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},!1}}return!0}isObstacleOwnJumperPad(t){if(!this.currentTrace?.jumpers)return!1;for(const e of this.currentTrace.jumpers){const n=Math.sqrt((t.center.x-e.start.x)**2+(t.center.y-e.start.y)**2),s=Math.sqrt((t.center.x-e.end.x)**2+(t.center.y-e.end.y)**2),o=Math.max(t.width,t.height)/2+.01;if(n<o||s<o)return!0}return!1}getClearanceAtPosition(t){if(!this.currentTrace)return 1/0;const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.nominalTraceWidth;let s=1/0;if(this.lastCollidingObstacles=[],this.lastCollidingRoutes=[],this.obstacleSHI){const o=this.obstacleSHI.searchArea(t.x,t.y,n,n);for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.connMap?.areIdsConnected(e,n.obstacleId))continue;let o=!1;if(this.connMap)for(const t of n.connectedTo)if(this.connMap.areIdsConnected(e,t)){o=!0;break}if(o)continue;if(this.isObstacleOwnJumperPad(n))continue;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,a=n.center.y-n.height/2,c=n.center.y+n.height/2,h=Math.max(i-t.x,0,t.x-r),l=Math.max(a-t.y,0,t.y-c),d=Math.sqrt(h*h+l*l);d<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingObstacles.push(n),d<s&&(s=d)}}const o=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:t,distance:n}of o){const o=t.rootConnectionName??t.connectionName;if(o===e)continue;if(this.connMap?.areIdsConnected(e,o))continue;const i=n-(t.traceThickness??.15)/2;i<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingRoutes.push(t),i<s&&(s=i)}return this.lastClearance=s,s}finalizeCurrentTrace(t){if(!this.currentTrace)return;const e={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:t,viaDiameter:this.currentTrace.viaDiameter,route:[...this.currentTrace.route],vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(e),this.currentTrace=null,this.cursorPosition=null,this.hasInsufficientClearance=!1}visualize(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:`Trace Width Solver (schedule: [${this.TRACE_WIDTH_SCHEDULE.map(t=>t.toFixed(2)).join(", ")}]mm, fallback: ${this.minTraceWidth.toFixed(2)}mm, margin: ${this.obstacleMargin.toFixed(2)}mm)`},e=new Set(this.lastCollidingObstacles.map(t=>t.obstacleId)),n=new Set(this.lastCollidingRoutes.map(t=>t.connectionName));for(const n of this.obstacles){const s=e.has(n.obstacleId),o=n.zLayers?.includes(0),i=n.zLayers?.includes(1);let r;r=s?"rgba(255, 0, 0, 0.6)":o&&i?"rgba(128, 0, 128, 0.15)":o?"rgba(255, 0, 0, 0.15)":i?"rgba(0, 0, 255, 0.15)":"rgba(128, 128, 128, 0.15)",t.rects.push({center:n.center,width:n.width,height:n.height,fill:r,stroke:s?"red":void 0,label:s?`COLLIDING: ${n.obstacleId??"obstacle"}`:`${n.obstacleId??"obstacle"} (Z: ${n.zLayers?.join(", ")})`})}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=e.traceThickness===this.nominalTraceWidth,s=e.traceThickness===this.TRACE_WIDTH_SCHEDULE[1],o=n?"green":s?"yellow":"orange";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],i=e.route[n+1];s.insideJumperPad&&i.insideJumperPad||s.z===i.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:i.x,y:i.y}],strokeColor:o,strokeWidth:e.traceThickness,label:`${e.connectionName} (w=${e.traceThickness.toFixed(2)})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Vh(e.jumpers,{color:o,label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}if(this.currentTrace){for(let e=0;e<this.currentTrace.route.length-1;e++){const n=this.currentTrace.route[e],s=this.currentTrace.route[e+1];n.insideJumperPad&&s.insideJumperPad||n.z===s.z&&t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"cyan",strokeWidth:this.currentTrace.traceThickness??this.minTraceWidth,label:`Processing: ${this.currentTrace.connectionName}`})}this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentTargetWidth/2,stroke:this.hasInsufficientClearance?"red":"green",fill:"none",label:`Testing width: ${this.currentTargetWidth.toFixed(2)}mm (clearance: ${this.lastClearance.toFixed(2)}mm)`}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}))}for(const e of this.unprocessedRoutes){if(0===e.route.length)continue;const s=n.has(e.connectionName);for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:s?"rgba(255, 0, 0, 0.8)":"rgba(128, 128, 128, 0.3)",strokeWidth:e.traceThickness??this.minTraceWidth,label:s?`COLLIDING: ${e.connectionName}`:e.connectionName})}}return t}getHdRoutesWithWidths(){return this.hdRoutesWithWidths}};function Cl(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Tl=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipelineSolver2_PortPointPathing"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;inputNodeWithPortPoints=[];cacheProvider=null;pipelineDef=[Cl("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Cl("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Cl("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Cl("availableSegmentPointSolver",Fn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Cl("portPointPathingSolver",Ah,t=>{this.inputNodeWithPortPoints=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle}));const e=new Map(this.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,t])),n=t.availableSegmentPointSolver;for(const t of n.sharedEdgeSegments)for(const n of t.portPoints){const[t,s]=n.nodeIds,o={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,s],distToCentermostPortOnZ:n.distToCentermostPortOnZ},i=e.get(t);i&&i.portPoints.push(o)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:this.inputNodeWithPortPoints,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:200,hyperParameters:{NODE_PF_MAX_PENALTY:100,FORCE_OFF_BOARD_FREQUENCY:0,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4}}]}),Cl("multiSectionPortPointOptimizer",Dh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints,effort:t.effort}]}),Cl("uniformPortDistributionSolver",Ae,t=>[{nodeWithPortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Cl("highDensityRouteSolver",dh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),Cl("highDensityStitchSolver",Kh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Cl("traceSimplificationSolver",Il,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Cl("traceWidthSolver",_l,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.srj.outline,m=[];if(m.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),f&&f.length>=2){const t=f.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),m.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const g={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:m},y=[g,t,e,n,s,o,i,r,a,c,h,l,d?Bn(g,d):null,u,p,this.solved?Bn(g,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...y)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},El=Tl,wl=class extends Ln{getSolverName(){return"CapacityEdgeToPortSegmentSolver"}nodes;edges;capacityPaths;nodeMap;nodeEdgeMap;unprocessedNodeIds;nodePortSegments;colorMap;constructor({nodes:t,edges:e,capacityPaths:n,colorMap:s}){super(),this.nodes=t,this.edges=e,this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Dn(e),this.capacityPaths=n,this.colorMap=s??{},this.unprocessedNodeIds=[...new Set(n.flatMap(t=>t.nodeIds))],this.nodePortSegments=new Map}step(){const t=this.unprocessedNodeIds.pop();if(!t)return void(this.solved=!0);const e=[];for(const n of this.capacityPaths){const s=n.nodeIds.indexOf(t);-1!==s&&e.push({path:n,indexOfNodeInPath:s})}const n=this.nodeMap.get(t),s=[];for(const{path:o,indexOfNodeInPath:i}of e){const e=o.nodeIds[i-1],r=o.nodeIds[i+1];for(const i of[e,r]){const e=this.nodeMap.get(i);if(!e)continue;const r=Rl(n,e),a=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===a.length)continue;const c={capacityMeshNodeId:t,start:r.start,end:r.end,connectionNames:[o.connectionName],rootConnectionNames:o.rootConnectionName?[o.rootConnectionName]:void 0,availableZ:a};s.push(c)}}const o=function(t){const e=[],n=t.map(t=>({...t,connectionNames:[...t.connectionNames],rootConnectionNames:t.rootConnectionNames?[...t.rootConnectionNames]:[],availableZ:[...t.availableZ].sort((t,e)=>t-e)}));for(;n.length>0;){const t=n.pop();let s=!1;for(let n=0;n<e.length;n++){const o=e[n],i=Al(o.start,t.start)&&Al(o.end,t.end)||Al(o.start,t.end)&&Al(o.end,t.start),r=zl(o.availableZ,t.availableZ);if(i&&r){const e=new Set(o.connectionNames);t.connectionNames.forEach(t=>e.add(t)),o.connectionNames=Array.from(e);const n=new Set(o.rootConnectionNames||[]);t.rootConnectionNames?.forEach(t=>n.add(t)),o.rootConnectionNames=Array.from(n),s=!0;break}}s||e.push(t)}return e}(s);this.nodePortSegments.set(t,o)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};return this.nodePortSegments.forEach((e,n)=>{this.nodeMap.get(n);e.forEach(e=>{e.start.x,e.end.x;for(let s=0;s<e.connectionNames.length;s++){const o={x:.05*Math.max(...e.availableZ),y:.05*Math.max(...e.availableZ)},i={x:(e.start.x+e.end.x)/2,y:(e.start.y+e.end.y)/2},r={x:i.x+o.x,y:i.y+o.y};o.x>0&&t.lines.push({points:[i,r],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5"}),t.points.push({x:r.x,y:r.y,label:`${n}: ${e.connectionNames.join(", ")}\navailableZ: ${e.availableZ.join(",")}\nnodePortSegmentId: ${e.nodePortSegmentId}`}),t.lines.push({points:[e.start,e.end],strokeColor:Nn(this.colorMap[e.connectionNames[s]],.6)})}})}),t}};function Rl(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)};if(n.end-n.start<s.end-s.start){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}var Ol=1e-9;function Al(t,e){return Math.abs(t.x-e.x)<Ol&&Math.abs(t.y-e.y)<Ol}function zl(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}var Ll=class{constructor(t){this.targets=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=Math.floor(n.bounds.minX/this.CELL_SIZE)*this.CELL_SIZE,o=Math.floor(n.bounds.minY/this.CELL_SIZE)*this.CELL_SIZE,i=n.bounds.maxX,r=n.bounds.maxY;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=5;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getTargetsInArea(t,e,n,s){const o=[],i=new Set,r=Math.floor((t-n/2)/this.CELL_SIZE)*this.CELL_SIZE,a=Math.floor((e-s/2)/this.CELL_SIZE)*this.CELL_SIZE,c=t+n/2,h=e+s/2;for(let t=r;t<=c;t+=this.CELL_SIZE)for(let e=a;e<=h;e+=this.CELL_SIZE){const n=this.getBucketKey(t,e),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},Dl=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.MAX_DEPTH=e?.capacityDepth??this.MAX_DEPTH,this.MAX_ITERATIONS=1e5,this.layerCount=t.layerCount??2,this.outlinePolygon=t.outline&&t.outline.length>=3?t.outline:void 0;const n={x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},s={width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},o=Math.max(s.width,s.height);this.unfinishedNodes=[{capacityMeshNodeId:this.getNextNodeId(),center:n,width:o,height:o,layer:"top",availableZ:Array.from({length:this.layerCount},(t,e)=>e),_depth:0,_containsTarget:!0,_containsObstacle:!0,_completelyInsideObstacle:!1}],this.finishedNodes=[],this.nodeToXYOverlappingObstaclesMap=new Map,this.obstacleZLayersByObstacle=new WeakMap;const i=hl(this.srj.obstacles,this.layerCount);for(const[t,e]of this.srj.obstacles.entries())this.obstacleZLayersByObstacle.set(e,i[t].zLayers);this.obstacleTree=new el("flatbush",this.srj.obstacles),this.targets=this.computeTargets(),this.targetTree=new Ll(this.targets)}getSolverName(){return"CapacityMeshNodeSolver"}unfinishedNodes;finishedNodes;nodeToXYOverlappingObstaclesMap;layerCount;outlinePolygon;MAX_DEPTH=4;targets;targetTree;obstacleTree;obstacleZLayersByObstacle;computeTargets(){const t=[];for(const e of this.srj.connections)for(const n of e.pointsToConnect){const s=Tn(n),o=this.obstacleTree.searchArea(n.x,n.y,.01,.01).filter(t=>{const e=this.getObstacleZLayers(t);return!(!e||0===e.length)&&e.some(t=>s.some(e=>t===wn(e,this.layerCount)))});let i={minX:n.x-.005,minY:n.y-.005,maxX:n.x+.005,maxY:n.y+.005};o.length>0&&(i={minX:Math.min(...o.map(t=>t.center.x-t.width/2)),minY:Math.min(...o.map(t=>t.center.y-t.height/2)),maxX:Math.max(...o.map(t=>t.center.x+t.width/2)),maxY:Math.max(...o.map(t=>t.center.y+t.height/2))});const r={...n,connectionName:e.name,availableZ:s.map(t=>wn(t,this.layerCount)),bounds:i};t.push(r)}return t}getNodeBounds(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}getNodeRect(t){return{center:{x:t.center.x,y:t.center.y},width:t.width,height:t.height}}_nextNodeCounter=0;getNextNodeId(){return"cn"+this._nextNodeCounter++}getCapacityFromDepth(t){return(this.MAX_DEPTH-t+1)**2}getTargetIfNodeContainsTarget(t){const e=t.width>4*this.targetTree.CELL_SIZE?this.targets:this.targetTree.getTargetsInArea(t.center.x,t.center.y,t.width,t.height);for(const n of e)if(n.bounds.minX<=t.center.x+t.width/2&&n.bounds.maxX>=t.center.x-t.width/2&&n.bounds.minY<=t.center.y+t.height/2&&n.bounds.maxY>=t.center.y-t.height/2&&n.availableZ.some(e=>t.availableZ.includes(e)))return n;return null}getXYOverlappingObstacles(t){const e=this.nodeToXYOverlappingObstaclesMap.get(t.capacityMeshNodeId);if(e)return e;const n=[],s=this.getNodeBounds(t),o=s.minX,i=s.maxX,r=s.minY,a=s.maxY,c=t._parent?this.getXYOverlappingObstacles(t._parent):this.srj.obstacles;for(const t of c){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,c=t.center.y-t.height/2,h=t.center.y+t.height/2;i>=e&&o<=s&&a>=c&&r<=h?n.push(t):(o>=e&&i<=s&&r>=c&&a<=h||e>=o&&s<=i&&c>=r&&h<=a)&&n.push(t)}return this.nodeToXYOverlappingObstaclesMap.set(t.capacityMeshNodeId,n),n}getXYZOverlappingObstacles(t){const e=this.getXYOverlappingObstacles(t),n=[];for(const s of e)t.availableZ.some(t=>this.getObstacleZLayers(s).includes(t))&&n.push(s);return n}doesNodeOverlapObstacle(t){if(this.getXYZOverlappingObstacles(t).length>0)return!0;const e=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}return e.minX<this.srj.bounds.minX||e.maxX>this.srj.bounds.maxX||e.minY<this.srj.bounds.minY||e.maxY>this.srj.bounds.maxY}isNodeCompletelyInsideObstacle(t){const e=this.getXYZOverlappingObstacles(t),n=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!Z(e,this.outlinePolygon))return!0}for(const t of e){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2;if(n.minX>=e&&n.maxX<=s&&n.minY>=o&&n.maxY<=i)return!0}return!1}getChildNodes(t){if(t._depth===this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s={capacityMeshNodeId:this.getNextNodeId(),center:o,width:n.width,height:n.height,layer:t.layer,availableZ:t.availableZ,_depth:(t._depth??0)+1,_parent:t};s._containsObstacle=this.doesNodeOverlapObstacle(s);const i=this.getTargetIfNodeContainsTarget(s);i&&(s._targetConnectionName=i.connectionName,s.availableZ=i.availableZ,s._containsTarget=!0),s._containsObstacle&&(s._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(s)),s._completelyInsideObstacle&&!s._containsTarget||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||!(!t._containsObstacle||t._completelyInsideObstacle))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t);e?s.push(t):e||t._containsObstacle?!e&&t._containsTarget&&n.push(t):n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Mesh Visualization"};if(this.outlinePolygon&&this.outlinePolygon.length>=2){const e=this.outlinePolygon.map(t=>({x:t.x,y:t.y}));e.push({...e[0]}),t.lines.push({points:e,strokeColor:"rgba(0, 136, 255, 0.95)",label:"outline"});for(const e of this.outlinePolygon)t.points.push({x:e.x,y:e.y,color:"rgba(0, 136, 255, 0.95)"})}for(const e of this.srj.obstacles){const n=this.getObstacleZLayers(e);t.rects.push({center:e.center,width:e.width,height:e.height,fill:1===n.length&&n.includes(1)?"rgba(0,0,255,0.3)":"rgba(255,0,0,0.3)",stroke:"red",label:["obstacle",`z: ${n.join(",")}`].join("\n")})}const e=[...this.finishedNodes,...this.unfinishedNodes];for(const n of e){const e=Math.min(...n.availableZ),s=this.unfinishedNodes.length>0&&n===this.unfinishedNodes[this.unfinishedNodes.length-1];t.rects.push({center:{x:n.center.x+e*n.width*.05,y:n.center.y-e*n.width*.05},width:Math.max(n.width-2,.8*n.width),height:Math.max(n.height-2,.8*n.height),fill:n._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[n.availableZ.join(",")]??"rgba(0,200,200,0.1)",stroke:s?"rgba(255,165,0,0.5)":void 0,label:[n.capacityMeshNodeId,`availableZ: ${n.availableZ.join(",")}`,`target? ${n._containsTarget??!1}`,`obs? ${n._containsObstacle??!1}`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`capacity: ${xh(n).toFixed(2)}`].join("\n")})}return t.rects.sort((t,e)=>t.center.y-e.center.y),this.srj.connections.forEach((e,n)=>{const s=Sn[n%Sn.length];for(const o of e.pointsToConnect){const e=Tn(o);t.points.push({x:o.x,y:o.y,label:`conn-${n} (${e.join(",")})`,color:s})}}),t}getObstacleZLayers(t){return this.obstacleZLayersByObstacle.get(t)??[]}},Fl=class extends Dl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e,this.VIA_DIAMETER=t.minViaDiameter??this.VIA_DIAMETER}getSolverName(){return"CapacityMeshNodeSolver2_NodeUnderObstacle"}VIA_DIAMETER=.6;OBSTACLE_MARGIN=.1;OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES=.2;isNodeCompletelyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);if(!Z(e,this.outlinePolygon))return!0}return t.center.x+t.width/2<this.srj.bounds.minX||t.center.x-t.width/2>this.srj.bounds.maxX||t.center.y+t.height/2<this.srj.bounds.minY||t.center.y-t.height/2>this.srj.bounds.maxY}isNodePartiallyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);return!!Z(e,this.outlinePolygon)&&!q(e,this.outlinePolygon)}return t.center.x-t.width/2<this.srj.bounds.minX||t.center.x+t.width/2>this.srj.bounds.maxX||t.center.y-t.height/2<this.srj.bounds.minY||t.center.y+t.height/2>this.srj.bounds.maxY}getObstacleCoveragePercentage(t){const e=this.getXYZOverlappingObstacles(t);if(0===e.length)return 0;const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=t.width*t.height;let a=0;for(const t of e){const e=Math.max(n,t.center.x-t.width/2),r=Math.min(s,t.center.x+t.width/2),c=Math.max(o,t.center.y-t.height/2),h=Math.min(i,t.center.y+t.height/2);if(e<r&&c<h){a+=(r-e)*(h-c)}}return a/r}shouldFilterSingleLayerNodeForObstacle(t){if(1!==t.availableZ.length)return!1;if(!t._containsObstacle)return!1;return this.getObstacleCoveragePercentage(t)>this.OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES}shouldFilterNodeForObstacle(t){return!!t._containsObstacle&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}createChildNodeAtPosition(t,e){const n={capacityMeshNodeId:this.getNextNodeId(),center:e.center,width:e.width,height:e.height,layer:t.layer,availableZ:e.availableZ,_depth:e._depth??(t._depth??0)+1,_parent:t},s=this.getXYZOverlappingObstacles(n);n._containsObstacle=s.length>0||this.isNodePartiallyOutsideBounds(n);const o=this.getTargetIfNodeContainsTarget(n);return o&&(n._targetConnectionName=o.connectionName,n._containsTarget=!0),n._containsObstacle&&(n._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(n)),n}getZSubdivisionChildNodes(t){if(1===t.availableZ.length)return[];const e=[],n=t.availableZ.map(t=>[t]);for(const s of n){const n=this.createChildNodeAtPosition(t,{center:{...t.center},width:t.width,height:t.height,availableZ:s,_depth:t._depth});this.isNodeCompletelyOutsideBounds(n)||e.push(n)}return e}getChildNodes(t){if(t._depth>=this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s=this.createChildNodeAtPosition(t,{center:o,width:n.width,height:n.height,availableZ:t.availableZ});this.isNodeCompletelyOutsideBounds(s)||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(1===t.availableZ.length&&t._depth<=this.MAX_DEPTH||!(!t._containsObstacle||t._completelyInsideObstacle)))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e&&(t._containsObstacle||t.width<this.VIA_DIAMETER+this.OBSTACLE_MARGIN);if(e)s.push(t);else if(e||this.shouldFilterNodeForObstacle(t)||o)if(!e&&t._containsTarget)if(o){const e=this.getZSubdivisionChildNodes(t);n.push(...e.filter(t=>t._containsTarget||!this.shouldFilterNodeForObstacle(t)))}else n.push(t);else o&&n.push(...this.getZSubdivisionChildNodes(t).filter(t=>!this.shouldFilterNodeForObstacle(t)));else n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},Yl=class extends Ln{getSolverName(){return"CapacitySegmentToPointSolver"}unsolvedSegments;solvedSegments;nodeMap;colorMap;constructor({segments:t,colorMap:e,nodes:n}){super(),this.MAX_ITERATIONS=1e5,this.unsolvedSegments=t,this.solvedSegments=[],this.colorMap=e??{},this.nodeMap=Object.fromEntries(n.map(t=>[t.capacityMeshNodeId,t]))}_step(){let t=!1;const e=[...this.unsolvedSegments];for(const n of e){const e=n.connectionNames.length;if((!("assignedPoints"in n)||n.assignedPoints?.length!==e)&&1===e){const e={x:(n.start.x+n.end.x)/2,y:(n.start.y+n.end.y)/2,z:n.availableZ[0]};n.assignedPoints=[{connectionName:n.connectionNames[0],rootConnectionName:n.rootConnectionNames?.[0],point:e}],this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}}if(!t&&e.length>0){let n=e[0];for(const t of e)t.connectionNames.length<n.connectionNames.length&&(n=t);const s=[...n.connectionNames].sort(),o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=s.length,a=[];for(let t=1;t<=r;t++){const e=t/(r+1);a.push({x:n.start.x+o*e,y:n.start.y+i*e,z:n.availableZ[0]})}n.assignedPoints=s.map((t,e)=>({connectionName:t,rootConnectionName:n.rootConnectionNames?.[n.connectionNames.indexOf(t)],point:a[e]})),this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}0===this.unsolvedSegments.length&&(this.solved=!0)}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.solvedSegments){const n=e.capacityMeshNodeId,s=this.nodeMap[n];t.has(n)||t.set(n,{capacityMeshNodeId:n,portPoints:[],center:s.center,width:s.width,height:s.height}),t.get(n).portPoints.push(...e.assignedPoints.map(t=>({...t.point,connectionName:t.connectionName})))}return Array.from(t.values())}visualize(){const t={points:[],lines:this.solvedSegments.map(t=>({points:[t.start,t.end],step:4})),rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Segment to Point Solver"};for(let e=0;e<this.solvedSegments.length;e++){const n=this.solvedSegments[e];for(let e=0;e<n.assignedPoints.length;e++){const s=n.assignedPoints[e],o={x:s.point.x,y:s.point.y},i={x:s.point.x+.05*s.point.z,y:s.point.y+.05*s.point.z};0!==s.point.z&&t.lines.push({points:[o,i],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5",step:4}),t.points.push({x:i.x,y:i.y,label:[`${n.capacityMeshNodeId}-${s.connectionName}`,`z: ${n.availableZ.join(",")}`,`nodePortSegmentId: ${n.nodePortSegmentId}`].join("\n"),color:this.colorMap[s.connectionName],step:4})}}const e=[],n={};for(const t of this.solvedSegments){const e=t.capacityMeshNodeId;n[e]||(n[e]={});for(const s of t.assignedPoints)n[e][s.connectionName]||(n[e][s.connectionName]=[]),n[e][s.connectionName].push({x:s.point.x,y:s.point.y})}for(const t in n)for(const s in n[t]){const o=n[t][s];o.length>1&&e.push({points:o,step:4,strokeDash:"5 5",strokeColor:this.colorMap[s]||"#000"})}return t.lines.push(...e),t}},Xl=(t,e={})=>{const n=Math.min(...t.availableZ);return{center:!e.rectMargin||e.zOffset?{x:t.center.x+n*t.width*(e.zOffset??.05),y:t.center.y-n*t.width*(e.zOffset??.05)}:t.center,width:e.rectMargin?t.width-2*e.rectMargin:Math.max(t.width-.5,.8*t.width),height:e.rectMargin?t.height-2*e.rectMargin:Math.max(t.height-.5,.8*t.height),fill:t._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[t.availableZ.join(",")]??"rgba(0,200,200,0.1)",layer:`z${t.availableZ.join(",")}`,label:[t.capacityMeshNodeId,`availableZ: ${t.availableZ.join(",")}`,""+(t._containsTarget?"containsTarget":""),""+(t._containsObstacle?"containsObstacle":"")].filter(Boolean).join("\n")}},kl=class extends Ln{getSolverName(){return"CapacityPathingSolver"}connectionsWithNodes;usedNodeCapacityMap;simpleRouteJson;nodes;edges;GREEDY_MULTIPLIER=1.1;MAX_CANDIDATES_IN_MEMORY=1e5;nodeMap;nodeEdgeMap;connectionNameToGoalNodeIds;colorMap;maxDepthOfNodes;activeCandidateStraightLineDistance;debug_lastNodeCostMap;hyperParameters;constructor({simpleRouteJson:t,nodes:e,edges:n,colorMap:s,MAX_ITERATIONS:o=1e6,hyperParameters:i={}}){super(),this.MAX_ITERATIONS=o,this.simpleRouteJson=t,this.nodes=e,this.edges=n,this.colorMap=s??{};const{connectionsWithNodes:r,connectionNameToGoalNodeIds:a}=this.getConnectionsWithNodes();this.connectionsWithNodes=r,this.connectionNameToGoalNodeIds=a,this.hyperParameters=i,this.usedNodeCapacityMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,0])),this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Dn(this.edges),this.maxDepthOfNodes=Math.max(...this.nodes.map(t=>t._depth??0)),this.debug_lastNodeCostMap=new Map}getTotalCapacity(t){const e=t._depth??0;return(this.maxDepthOfNodes-e+1)**2}getConnectionsWithNodes(){const t=[],e=this.nodes.filter(t=>t._containsTarget),n=new Map;for(const s of this.simpleRouteJson.connections){const o=[];for(const t of s.pointsToConnect){let n=this.nodes[0],s=Number.MAX_VALUE;for(const o of e){const e=Math.sqrt((o.center.x-t.x)**2+(o.center.y-t.y)**2);e<s&&(s=e,n=o)}o.push(n)}if(o.length<2)throw new Error(`Not enough nodes for connection "${s.name}", only ${o.length} found`);n.set(s.name,o.map(t=>t.capacityMeshNodeId)),t.push({connection:s,nodes:o,pathFound:!1,straightLineDistance:k(o[0].center,o[o.length-1].center)})}return t.sort((t,e)=>t.straightLineDistance-e.straightLineDistance),{connectionsWithNodes:t,connectionNameToGoalNodeIds:n}}currentConnectionIndex=0;candidates;visitedNodes;computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)}getBacktrackedPath(t){const e=[];let n=t;for(;n;)e.push(n.node),n=n.prevCandidate;return e}getNeighboringNodes(t){return this.nodeEdgeMap.get(t.capacityMeshNodeId).flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t))}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,rootConnectionName:e.connection.rootConnectionName,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}doesNodeHaveCapacityForTrace(t,e){const n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=this.getTotalCapacity(t);if(1===t.availableZ.length&&!t._containsTarget&&n>0)return!1;let o=0;return t.availableZ.length>1&&1===e.availableZ.length&&(o+=.5),n+o<s}canTravelThroughObstacle(t,e){const n=this.connectionNameToGoalNodeIds.get(e);return n?.includes(t.capacityMeshNodeId)??!1}getDistanceBetweenNodes(t,e){return Math.sqrt((t.center.x-e.center.x)**2+(t.center.y-e.center.y)**2)}reduceCapacityAlongPath(t){for(const e of t.path??[])this.usedNodeCapacityMap.set(e.capacityMeshNodeId,this.usedNodeCapacityMap.get(e.capacityMeshNodeId)+1)}isConnectedToEndGoal(t,e){return this.nodeEdgeMap.get(t.capacityMeshNodeId).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}_step(){const t=this.connectionsWithNodes[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const[e,n]=t.nodes;this.candidates||(this.candidates=[{prevCandidate:null,node:e,f:0,g:0,h:0}],this.debug_lastNodeCostMap=new Map,this.visitedNodes=new Set([e.capacityMeshNodeId]),this.activeCandidateStraightLineDistance=k(e.center,n.center)),this.candidates.sort((t,e)=>t.f-e.f);const s=this.candidates.shift();if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!s)return console.error(`Ran out of candidates on connection ${t.connection.name}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,void(this.failed=!0);if(this.isConnectedToEndGoal(s.node,n))return t.path=this.getBacktrackedPath({prevCandidate:s,node:n,f:0,g:0,h:0}),this.reduceCapacityAlongPath(t),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);const o=this.getNeighboringNodes(s.node);for(const t of o){if(this.visitedNodes?.has(t.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(t,s.node))continue;const e=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;if(t._containsObstacle&&!this.canTravelThroughObstacle(t,e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+i*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:r,g:o,h:i});const a={prevCandidate:s,node:t,f:r,g:o,h:i};this.candidates.push(a)}this.visitedNodes.add(s.node.capacityMeshNodeId)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.connectionsWithNodes)for(let e=0;e<this.connectionsWithNodes.length;e++){const n=this.connectionsWithNodes[e];if(n.path&&n.path.length>0){const s=n.path.map(({center:{x:t,y:n},width:s,availableZ:o})=>({x:t+.005*s*(e%10+e%19),y:n+.005*s*(e%10+e%19),availableZ:o}));t.lines.push({points:s,strokeColor:this.colorMap[n.connection.name]});for(let e=0;e<s.length;e++){const o=s[e];t.points.push({x:o.x,y:o.y,label:[`conn: ${n.connection.name}`,`node: ${n.path[e].capacityMeshNodeId}`,`z: ${o.availableZ.join(",")}`].join("\n")})}}}for(const e of this.nodes){const n=this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,s=this.getTotalCapacity(e),o=this.debug_lastNodeCostMap.get(e.capacityMeshNodeId);t.rects.push({...Xl(e,{rectMargin:.025,zOffset:.01}),label:[`${e.capacityMeshNodeId}`,`${n}/${s}`,`${e.width.toFixed(2)}x${e.height.toFixed(2)}`,`g: ${void 0!==o?.g?o.g.toFixed(2):"?"}`,`h: ${void 0!==o?.h?o.h.toFixed(2):"?"}`,`f: ${void 0!==o?.f?o.f.toFixed(2):"?"}`,`z: ${e.availableZ.join(", ")}`].join("\n"),stroke:n>s+.5?"red":void 0})}if(this.connectionsWithNodes)for(const e of this.connectionsWithNodes)if(e.connection?.pointsToConnect)for(const n of e.connection.pointsToConnect)t.points.push({x:n.x,y:n.y,label:[`pointsToConnect ${e.connection.name}`].join("\n")});let e=this.connectionsWithNodes[this.currentConnectionIndex];if(!this.candidates&&this.currentConnectionIndex>0&&!this.connectionsWithNodes[this.currentConnectionIndex-1].path&&(e=this.connectionsWithNodes[this.currentConnectionIndex-1]),e){const[n,s]=e.connection.pointsToConnect;t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"red",strokeDash:"10 5"})}if(this.candidates){const e=this.candidates.slice(0,5),n=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;e.forEach((e,s)=>{const o=.5*(1-s/5),i=this.getBacktrackedPath(e);t.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:Nn(this.colorMap[n]??"red",1-o)})})}return t}},$l=class extends kl{getSolverName(){return"CapacityPathingSolver5"}NEGATIVE_CAPACITY_PENALTY_FACTOR=1;REDUCED_CAPACITY_PENALTY_FACTOR=1;constructor(...t){super(...t),this.GREEDY_MULTIPLIER=2.5}get maxCapacityFactor(){return this.hyperParameters.MAX_CAPACITY_FACTOR??1}getTotalCapacity(t){return xh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){const e=t.width+t.height,n=.05,s=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0);if(s>2)return n;return(e-n)*Math.max(1,(2-s)/(e-n))+n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}},Bl=class extends $l{getSolverName(){return"CapacityPathingGreedySolver"}doesNodeHaveCapacityForTrace(t,e){return!0}getNodeCapacityPenalty(t){const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+2*Math.abs(e))*n}};function jl(t,e,n){const s=e.x-t.x,o=e.y-t.y;if(Math.abs(s)<1e-9&&Math.abs(o)<1e-9)return t;const i=n.width/2,r=n.height/2,a=n.center.x-i,c=n.center.x+i,h=n.center.y-r,l=n.center.y+r;let d=0,u=1/0;if(Math.abs(s)>1e-9){const e=(a-t.x)/s,n=(c-t.x)/s;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.x<a||t.x>c)return t;if(Math.abs(o)>1e-9){const e=(h-t.y)/o,n=(l-t.y)/o;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.y<h||t.y>l)return t;if(u<d||d===1/0||d<-1e9)return t;return{x:t.x+s*d,y:t.y+o*d}}function Wl(t,e){const n=t.center,s=e.center,o=jl(n,s,t),i=jl(s,n,e),r=s.x-n.x,a=s.y-n.y,c=Math.sqrt(r*r+a*a);let h=o,l=i;if(c>1e-9){const n={x:r/c,y:a/c},s=.3*t.width,d=.3*e.width;s+d<Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)?(h={x:o.x+n.x*s,y:o.y+n.y*s},l={x:i.x-n.x*d,y:i.y-n.y*d}):(h=o,l=i)}return{lineStart:h,lineEnd:l}}var Hl=t=>{const{usedCapacity:e,totalCapacity:n,layerCount:s}=t;if(e<n)return 0;if(n<1&&e<=1)return 0;if(1===s&&e>1)return 1-.01**e;const o=e/n-1;return 1-Math.exp(-2*o)},Ul=(t,e,n)=>{if(n._containsTarget)return 0;if(t<=e)return 0;const s=1-Hl({usedCapacity:t,totalCapacity:e,layerCount:n.availableZ.length});return s<=0?-1e9:Math.log(s)},Vl=({totalNodeCapacityMap:t,usedNodeCapacityMap:e,nodeMap:n,sectionNodeIds:s})=>{let o=0;const i=s??new Set(e.keys());for(const s of i){if(!t.has(s))continue;const i=n.get(s);if(!i)continue;const r=t.get(s),a=e.get(s)??0;o+=Ul(a,r,i)}return o};function Gl({sectionNodes:t,sectionEdges:e,sectionConnectionTerminals:n,completedPaths:s,nodeMap:o,colorMap:i,centerNodeId:r,title:a,nodeOpacity:c=.1,usedNodeCapacityMap:h,totalCapacityMap:l}){const d={points:[],lines:[],rects:[],circles:[],title:a},u=new Set(t.map(t=>t.capacityMeshNodeId));for(const e of t){let t=`rgba(128, 128, 128, ${c})`,n=`rgba(128, 128, 128, ${c})`;const s=e.availableZ??[],o=s.includes(0),i=s.includes(1);o&&i?(t=`rgba(128, 0, 128, ${c})`,n=`rgba(128, 0, 128, ${c})`):o?(t=`rgba(0, 0, 255, ${c})`,n=`rgba(0, 0, 255, ${c})`):i&&(t=`rgba(255, 0, 0, ${c})`,n=`rgba(255, 0, 0, ${c})`),r&&e.capacityMeshNodeId===r&&(t=`rgba(0, 255, 0, ${c})`,n=`rgba(0, 128, 0, ${c})`),d.rects.push({...Xl(e),fill:t,stroke:n,label:`${e.capacityMeshNodeId}\n(Section Node)\nZ: ${s.join(",")}`});const a=d.rects.length-1;if(h&&l){const t=h.get(e.capacityMeshNodeId)??0,n=l.get(e.capacityMeshNodeId)??0,s=n>0?(t/n*100).toFixed(1):"N/A",o=Hl({usedCapacity:t,totalCapacity:n,layerCount:e.availableZ.length});d.rects[a].label+=`\n${t.toFixed(1)} / ${n.toFixed(1)}\n${s}% (Pf: ${(100*o).toFixed(1)}%)`,o>.2&&(d.rects[a].stroke=Nn("red",.7*(.8+c)))}}for(const t of e){const[e,n]=t.nodeIds,s=o.get(e),i=o.get(n);if(s&&i){const{lineStart:t,lineEnd:e}=Wl(s,i);d.lines.push({points:[t,e],strokeColor:`rgba(0, 0, 0, ${.2*Math.min(1,c/.1)})`})}}return n.forEach((t,e)=>{const n=o.get(t.startNodeId),s=o.get(t.endNodeId),r=i[t.connectionName]??"black",a=n&&u.has(n.capacityMeshNodeId),c=s&&u.has(s.capacityMeshNodeId),h=(e+e/50)%5;let l=0,p=0,f=0,m=0;if(a&&n){const e=.02*Math.min(n.width,n.height);l=e*h,p=e*h,d.points.push({x:n.center.x+l,y:n.center.y+p,color:r,label:`Start: ${t.connectionName}\n(${t.startNodeId})`}),d.lines.push({points:[{x:n.center.x,y:n.center.y},{x:n.center.x+l,y:n.center.y+p}],strokeColor:"gray",strokeDash:"2 2"})}if(c&&s){const e=.02*Math.min(s.width,s.height);f=e*h,m=e*h,d.points.push({x:s.center.x+f,y:s.center.y+m,color:r,label:`End: ${t.connectionName}\n(${t.endNodeId})`}),d.lines.push({points:[{x:s.center.x,y:s.center.y},{x:s.center.x+f,y:s.center.y+m}],strokeColor:"gray",strokeDash:"2 2"})}a&&c&&n&&s&&d.lines.push({points:[{x:n.center.x+l,y:n.center.y+p},{x:s.center.x+f,y:s.center.y+m}],strokeColor:r,strokeDash:"5 5"})}),s&&s.forEach((t,e)=>{if(t.path&&t.path.length>0){const n=i[t.connectionName]??"gray",s={x:(e+e/50)%5*.03,y:(e+e/50)%5*.03};d.lines.push({points:t.path.map(({center:{x:t,y:e}})=>({x:t+s.x,y:e+s.y})),strokeColor:Nn(n,.2)})}}),d}var Zl=class extends Ln{getSolverName(){return"CapacityPathingSingleSectionSolver"}GREEDY_MULTIPLIER=1.5;sectionNodes;sectionEdges;sectionConnectionTerminals;nodeMap;nodeEdgeMap;colorMap;usedNodeCapacityMap;totalNodeCapacityMap;centerNodeId;currentSectionScore=0;MAX_CANDIDATES_IN_MEMORY=1e4;currentConnectionIndex=0;candidates=null;visitedNodes=null;queuedNodes=null;activeCandidateStraightLineDistance;debug_lastNodeCostMap=new Map;maxCapacityFactor=1;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.centerNodeId=t.centerNodeId,this.sectionNodes=t.sectionNodes,this.sectionEdges=t.sectionEdges,this.sectionConnectionTerminals=t.sectionConnectionTerminals.map(t=>({...t,path:void 0})),this.nodeMap=t.nodeMap??new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=t.nodeEdgeMap??Dn(this.sectionEdges),this.colorMap=t.colorMap??{},this.usedNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,0])),this.totalNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,this.getTotalCapacity(t)]));const e=new Set(this.sectionNodes.map(t=>t.capacityMeshNodeId));this.currentSectionScore=Vl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:e}),t.hyperParameters?.SHUFFLE_SEED&&(this.sectionConnectionTerminals=Vn(this.sectionConnectionTerminals,t.hyperParameters?.SHUFFLE_SEED))}getTotalCapacity(t){return xh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){if(!this.nodeMap.has(t.capacityMeshNodeId))return 1/0;const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+e**2*4)*n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(e.push(n.node),!this.nodeMap.has(n.node.capacityMeshNodeId)){console.warn("Backtracked path went outside section bounds");break}n=n.prevCandidate}return e.reverse()}getNeighboringNodes(t){return this.nodeMap.has(t.capacityMeshNodeId)?this.nodeEdgeMap.get(t.capacityMeshNodeId)?.flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t)).filter(Boolean)??[]:[]}isConnectedToEndGoal(t,e){return!(!this.nodeMap.has(t.capacityMeshNodeId)||!this.nodeMap.has(e.capacityMeshNodeId))&&(this.nodeEdgeMap.get(t.capacityMeshNodeId)??[]).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}doesNodeHaveCapacityForTrace(t,e){return!0}reduceCapacityAlongPath(t){for(const e of t)if(this.usedNodeCapacityMap.has(e.capacityMeshNodeId)){const t=e.capacityMeshNodeId,n=this.nodeMap.get(t);if(!n){console.warn(`Node ${t} from path not found in section's nodeMap during score update.`);continue}const s=this.totalNodeCapacityMap.get(t),o=this.usedNodeCapacityMap.get(t)??0,i=Ul(o,s,n);this.currentSectionScore-=i;const r=o+1;this.usedNodeCapacityMap.set(t,r);const a=Ul(r,s,n);this.currentSectionScore+=a}}getSolvedSectionScore(){return this.currentSectionScore}_step(){const t=this.sectionConnectionTerminals[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const e=this.nodeMap.get(t.startNodeId),n=this.nodeMap.get(t.endNodeId);if(!e||!n)return console.error(`Start or end node not found in section for connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);this.candidates||this._setupAStar(e,n);const s=this.candidates;if(0===s.length)return void this._handleCandidatesExhausted(t);s.sort((t,e)=>t.f-e.f);const o=s.shift();if(s.length>this.MAX_CANDIDATES_IN_MEMORY&&s.splice(this.MAX_CANDIDATES_IN_MEMORY,s.length-this.MAX_CANDIDATES_IN_MEMORY),this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId)return void this._handleGoalReached(o,t,n);const i=this.getNeighboringNodes(o.node);for(const e of i){if(this.queuedNodes?.has(e.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(e,o.node))continue;if(e._containsObstacle){const n=e.capacityMeshNodeId===t.startNodeId,s=e.capacityMeshNodeId===t.endNodeId;if(!n&&!s)continue}const i=this.computeG(o,e,n),r=this.computeH(o,e,n),a=i+r*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(e.capacityMeshNodeId,{f:a,g:i,h:r});const c={prevCandidate:o,node:e,f:a,g:i,h:r};this.queuedNodes?.add(e.capacityMeshNodeId),s.push(c)}}computeProgress(){const t=this.sectionConnectionTerminals.length;if(0===t)return 1;let e=this.currentConnectionIndex/t;if(this.currentConnectionIndex<t&&this.candidates&&this.candidates.length>0&&this.activeCandidateStraightLineDistance&&this.activeCandidateStraightLineDistance>0){const n=this.candidates.reduce((t,e)=>e.f<t.f?e:t);e+=Math.max(0,Math.min(1,1-n.h/this.activeCandidateStraightLineDistance))/t}else this.solved&&(e=1);return Math.min(1,e)}_setupAStar(t,e){this.candidates=[{prevCandidate:null,node:t,f:0,g:0,h:0}],this.visitedNodes=new Set([t.capacityMeshNodeId]),this.debug_lastNodeCostMap=new Map,this.activeCandidateStraightLineDistance=k(t.center,e.center);const n=this.computeH(null,t,e);this.candidates[0].h=n,this.candidates[0].f=n*this.GREEDY_MULTIPLIER,this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:this.candidates[0].f,g:0,h:n}),this.queuedNodes=new Set([t.capacityMeshNodeId])}_handleCandidatesExhausted(t){console.error(`Ran out of candidates for section connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}_handleGoalReached(t,e,n){const s=this.getBacktrackedPath(t);e.path=s,this.reduceCapacityAlongPath(s),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}visualize(){const t=this.sectionConnectionTerminals.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connectionName,path:t.path})),e=Gl({sectionNodes:this.sectionNodes,sectionEdges:this.sectionEdges,sectionConnectionTerminals:this.sectionConnectionTerminals,completedPaths:t,nodeMap:this.nodeMap,colorMap:this.colorMap,centerNodeId:null,title:`Section Pathing: Conn ${this.currentConnectionIndex+1}/${this.sectionConnectionTerminals.length} (${this.sectionNodes.length} nodes)`,nodeOpacity:.1});for(const t of this.sectionNodes){const n=e.rects.findIndex(e=>e.label?.includes(t.capacityMeshNodeId));if(-1!==n){const s=this.debug_lastNodeCostMap.get(t.capacityMeshNodeId),o=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,i=this.getTotalCapacity(t),r=`${o.toFixed(1)}/${i.toFixed(1)}`,a=s?`f:${s.f.toFixed(1)} g:${s.g.toFixed(1)} h:${s.h.toFixed(1)}`:"cost:?";e.rects[n].label=[t.capacityMeshNodeId,`Cap: ${r}`,a,`Z: ${t.availableZ.join(",")}`].join("\n"),o>i&&(e.rects[n].stroke=Nn("red",.7))}}if(this.candidates&&this.candidates.length>0){const t=this.candidates.slice().sort((t,e)=>t.f-e.f).slice(0,5),n=this.sectionConnectionTerminals[this.currentConnectionIndex],s=n?.connectionName??"unknown",o=this.colorMap[s]??"purple";t.forEach((t,n)=>{const s=.8*(1-n/5),i=this.getBacktrackedPath(t);i.length>0&&e.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:Nn(o,1-s),strokeWidth:.05})})}return e}},ql=t=>Array.from({length:t},(t,e)=>e),Jl=class extends os{getSolverName(){return"HyperCapacityPathingSingleSectionSolver"}constructorParams;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.constructorParams=t}computeG(t){return-t.getSolvedSectionScore()}computeH(t){return 0}getCombinationDefs(){const t=this.constructorParams.sectionConnectionTerminals.length;return 2===t?[["orderings2_for2"]]:3===t?[["orderings6_for3"]]:4===t?[["orderings24_for4"]]:[["orderings30"]]}getFailureMessage(){return`All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`}getHyperParameterDefs(){return[{name:"orderings2_for2",possibleValues:ql(2).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings6_for3",possibleValues:ql(6).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings24_for4",possibleValues:ql(24).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings30",possibleValues:ql(30).map(t=>({SHUFFLE_SEED:t}))}]}generateSolver(t){return new Zl({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}onSolve({solver:t}){this.winningSolver=t}get centerNodeId(){return this.constructorParams.centerNodeId}get sectionNodes(){return this.constructorParams.sectionNodes}get sectionConnectionTerminals(){return this.winningSolver?.sectionConnectionTerminals}};import Kl from"object-hash";var Ql=t=>Math.floor(10*t)/10,td=class extends Jl{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;sectionNodeIdSet;cachedSectionConnectionTerminals=null;sectionScore=0;constructor(t){t.nodeMap=t.nodeMap??new Map(t.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),super(t),this.sectionNodeIdSet=new Set(t.sectionNodes.map(t=>t.capacityMeshNodeId)),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}_computeBfsOrderingOfNodesInSection(){const t=new Set(this.constructorParams.centerNodeId),e=[],n=[{ancestorCapacitySum:0,capacity:0,g:0,capacityMeshNodeId:this.constructorParams.centerNodeId}];for(;n.length>0;){n.sort((t,e)=>e.g-t.g);const s=n.pop();if(!s)break;e.push(s.capacityMeshNodeId);const o=this.constructorParams.nodeEdgeMap.get(s.capacityMeshNodeId).flatMap(t=>t.nodeIds).filter(e=>!t.has(e)).filter(t=>this.sectionNodeIdSet.has(t));for(const e of o){t.add(e);const o=this.constructorParams.nodeMap.get(e),i=xh(o);n.push({ancestorCapacitySum:s.g,capacity:i,g:s.g+i,capacityMeshNodeId:e})}}return e}computeCacheKeyAndTransform(){const t=this._computeBfsOrderingOfNodesInSection(),e=new Map,n=new Map;t.forEach((t,s)=>{const o=`node${s}`;e.set(t,o),n.set(o,t)});const s={};for(const n of t){const t=e.get(n),o=this.constructorParams.nodeMap.get(n),i=xh(o);s[t]=Ql(i).toFixed(1)}const o=new Set,i=[];for(const n of t){const t=e.get(n),s=this.constructorParams.nodeEdgeMap.get(n)??[];for(const r of s){const s=r.nodeIds.find(t=>t!==n);if(this.sectionNodeIdSet.has(s)){const n=[t,e.get(s)].sort(),r=`${n[0]}-${n[1]}`;o.has(r)||(i.push(n),o.add(r))}}}i.sort((t,e)=>t[0]!==e[0]?t[0].localeCompare(e[0]):t[1].localeCompare(e[1]));const r={},a=new Map,c=new Map;for(const t of this.constructorParams.sectionConnectionTerminals){const n=e.get(t.startNodeId),s=e.get(t.endNodeId),[o,i]=[n,s].sort(),h=`${o}->${i}`,l=c.get(h)??0;c.set(h,l+1);const d=`${o}->${i}::${l}`;r[d]={start:o,end:i},a.set(d,t.connectionName)}const h=`capacitypathing:${Kl({node_capacity_map:s,node_edge_map:i,terminals:r})}`,l={cacheSpaceToRealConnectionId:a,cacheSpaceToRealNodeId:n};return this.cacheKey=h,this.cacheToSolveSpaceTransform=l,{cacheKey:h,cacheToSolveSpaceTransform:l}}applyCachedSolution(t){if(!this.cacheToSolveSpaceTransform)return console.error("Cache transform not available, cannot apply cached solution."),void(this.failed=!0);if(!t.success)return this.failed=!0,void(this.cacheHit=!0);this.cachedSectionConnectionTerminals=[];const{cacheSpaceToRealNodeId:e,cacheSpaceToRealConnectionId:n}=this.cacheToSolveSpaceTransform;for(const[s,o]of Object.entries(t.solutionPaths)){const t=n.get(s);if(!t){console.warn(`Could not find real connection name for ${s}`);continue}const i=this.constructorParams.sectionConnectionTerminals.find(e=>e.connectionName===t);if(!i){console.warn(`Could not find original terminal for connection name ${t}`);continue}const r=o.map(n=>{const s=e.get(n);if(!s)throw new Error(`Could not map cache node ID ${n} to real node ID for connection ${t}`);const o=this.constructorParams.nodeMap.get(s);if(!o)throw new Error(`Could not find node with ID ${s} in nodeMap for connection ${t}`);return o});this.cachedSectionConnectionTerminals.push({...i,path:r})}this.sectionScore=t.sectionScore,this.solved=!0,this.cacheHit=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheKey)return void console.error("Cannot save to cache without cache key.");if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available, cannot save solution to cache.");let t;if(this.failed)t={success:!1};else{if(!this.solved)return;{const e={},{cacheSpaceToRealNodeId:n,cacheSpaceToRealConnectionId:s}=this.cacheToSolveSpaceTransform,o=new Map;for(const[t,e]of n)o.set(e,t);const i=new Map;for(const[t,e]of s)i.set(e,t);const r=[];if(super.sectionConnectionTerminals)for(const t of super.sectionConnectionTerminals)if(t.path&&t.path.length>0){const e=t.path.map(t=>t.capacityMeshNodeId);r.push([t.connectionName,e])}for(const[t,n]of r){const s=i.get(t);if(!s){console.warn(`Could not find cache space connection ID for ${t} when saving to cache.`);continue}const r=n.map(e=>{const n=o.get(e);if(!n)throw new Error(`Could not map real node ID ${e} to cache node ID for connection ${t} when saving to cache.`);return n});e[s]=r}t={success:!0,sectionScore:this.sectionScore,solutionPaths:e}}}try{this.cacheProvider?.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}get sectionConnectionTerminals(){return this.cacheHit&&this.solved&&this.cachedSectionConnectionTerminals?(console.log("returning the cached section connection terminals"),this.cachedSectionConnectionTerminals):super.sectionConnectionTerminals}visualize(){if(!this.cacheHit)return super.visualize();return Gl({sectionNodes:this.constructorParams.sectionNodes,sectionEdges:this.constructorParams.sectionEdges,sectionConnectionTerminals:this.cachedSectionConnectionTerminals,completedPaths:this.cachedSectionConnectionTerminals.map(t=>({connectionName:t.connectionName,path:t.path})),nodeMap:this.constructorParams.nodeMap,colorMap:this.constructorParams.colorMap,title:"CachedHyperCapacityPathingSingleSectionSolver"})}},ed=class extends Ln{getSolverName(){return"CapacityPathingMultiSectionSolver"}simpleRouteJson;nodes;edges;nodeEdgeMap;connectionsWithNodes=[];colorMap;initialSolver;cacheProvider;stage="initialization";nodeMap=new Map;allNodeIdsSet;usedNodeCapacityMap=new Map;totalNodeCapacityMap=new Map;nodeCapacityPercentMap=new Map;nodeOptimizationAttemptCountMap=new Map;currentSection=null;sectionSolver=null;currentScheduleIndex=0;stats;OPTIMIZATION_SCHEDULE=[{MAX_ATTEMPTS_PER_NODE:1,MAX_EXPANSION_DEGREES:3,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.05},{MAX_ATTEMPTS_PER_NODE:2,MAX_EXPANSION_DEGREES:5,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.2},{MAX_ATTEMPTS_PER_NODE:3,MAX_EXPANSION_DEGREES:7,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.9}];get currentSchedule(){return this.OPTIMIZATION_SCHEDULE[this.currentScheduleIndex]??null}constructor(t){super(),this.stats={successfulOptimizations:0,failedOptimizations:0,failedSectionSolvers:0,startingScore:0,scheduleScores:this.OPTIMIZATION_SCHEDULE.map(({MAX_EXPANSION_DEGREES:t})=>({maxExpansionDegrees:t,endingScore:0,endingHighestNodePf:0,sectionAttempts:0})),cacheHits:0,cacheMisses:0},this.MAX_ITERATIONS=t.MAX_ITERATIONS??1e7,this.cacheProvider=t.cacheProvider,this.simpleRouteJson=t.simpleRouteJson,this.nodes=t.nodes,this.edges=t.edges,this.nodeEdgeMap=Dn(this.edges),this.colorMap=t.colorMap??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Dn(this.edges),this.initialSolver=t.initialPathingSolver||new Bl({simpleRouteJson:this.simpleRouteJson,nodes:this.nodes,edges:this.edges,colorMap:this.colorMap}),this.activeSubSolver=this.initialSolver;for(const t of this.nodes){const e=this.initialSolver.getTotalCapacity(t);this.totalNodeCapacityMap.set(t.capacityMeshNodeId,e)}this.allNodeIdsSet=new Set(this.nodes.map(t=>t.capacityMeshNodeId))}_stepInitialization(){if(this.initialSolver?.step(),this.initialSolver?.failed)return this.failed=!0,void(this.error=this.initialSolver.error);if(this.initialSolver?.solved){this.usedNodeCapacityMap=new Map(this.initialSolver.usedNodeCapacityMap);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s),this.nodeOptimizationAttemptCountMap.set(t.capacityMeshNodeId,0)}this.connectionsWithNodes=this.initialSolver.connectionsWithNodes,this.stats.startingScore=Vl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet}),this.stage="section-optimization"}}_getNextNodeToOptimize(){let t=0,e=0,n=null;for(const s of this.nodes){if(s._containsTarget)continue;const o=this.nodeOptimizationAttemptCountMap.get(s.capacityMeshNodeId),i=this.totalNodeCapacityMap.get(s.capacityMeshNodeId),r=Hl({usedCapacity:this.usedNodeCapacityMap.get(s.capacityMeshNodeId)??0,totalCapacity:i,layerCount:s.availableZ.length}),a=r/(o+1);o<this.currentSchedule.MAX_ATTEMPTS_PER_NODE&&a>t&&r>this.currentSchedule.MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE&&(t=a,e=r,n=s.capacityMeshNodeId)}return n}getOverallScore(){let t=0;for(const e of this.nodes){if(e._containsTarget)continue;const n=this.totalNodeCapacityMap.get(e.capacityMeshNodeId),s=Hl({usedCapacity:this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,totalCapacity:n,layerCount:e.availableZ.length});s>t&&(t=s)}return{highestNodePf:t,score:Vl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet})}}_stepSectionOptimization(){if(!this.sectionSolver){const t=this._getNextNodeToOptimize();if(!t){const{highestNodePf:t,score:e}=this.getOverallScore();return this.stats.scheduleScores[this.currentScheduleIndex].endingHighestNodePf=t,this.stats.scheduleScores[this.currentScheduleIndex].endingScore=e,this.currentScheduleIndex++,void(this.currentSchedule||(this.solved=!0))}const e=(t=>{const{centerNodeId:e,connectionsWithNodes:n,nodeMap:s,edges:o,nodeEdgeMap:i,expansionDegrees:r}=t,a=new Set,c=[{nodeId:e,depth:0}];a.add(e);let h=0;for(;h<c.length;){const{nodeId:t,depth:e}=c[h++];if(e>=r)continue;const n=i.get(t)?.flatMap(e=>e.nodeIds.filter(e=>e!==t))??[];for(const t of n)a.has(t)||(a.add(t),c.push({nodeId:t,depth:e+1}))}const l=Array.from(a).map(t=>s.get(t)),d=o.filter(t=>{const[e,n]=t.nodeIds;return a.has(e)&&a.has(n)}),u=[];for(const t of n){if(!t.path)continue;let e=null,n=null;for(const n of t.path)if(a.has(n.capacityMeshNodeId)){e=n.capacityMeshNodeId;break}for(let e=t.path.length-1;e>=0;e--){const s=t.path[e];if(a.has(s.capacityMeshNodeId)){n=s.capacityMeshNodeId;break}}e&&n&&u.push({connectionName:t.connection.name,startNodeId:e,endNodeId:n})}return{sectionConnectionTerminals:u,sectionNodes:l,sectionEdges:d,centerNodeId:e}})({centerNodeId:t,connectionsWithNodes:this.connectionsWithNodes,nodeMap:this.nodeMap,edges:this.edges,expansionDegrees:this.currentSchedule.MAX_EXPANSION_DEGREES,nodeEdgeMap:this.nodeEdgeMap});this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++,this.currentSection=e,this.sectionSolver=new td({sectionNodes:this.currentSection.sectionNodes,sectionEdges:this.currentSection.sectionEdges,sectionConnectionTerminals:this.currentSection.sectionConnectionTerminals,colorMap:this.colorMap,centerNodeId:this.currentSection.centerNodeId,nodeEdgeMap:this.nodeEdgeMap,hyperParameters:{EXPANSION_DEGREES:this.currentSchedule.MAX_EXPANSION_DEGREES},cacheProvider:this.cacheProvider}),this.activeSubSolver=this.sectionSolver,this.nodeOptimizationAttemptCountMap.set(t,(this.nodeOptimizationAttemptCountMap.get(t)??0)+1)}if(this.sectionSolver.step(),(this.sectionSolver.failed||this.sectionSolver.solved)&&(this.sectionSolver.cacheHit?this.stats.cacheHits++:this.stats.cacheMisses++),this.sectionSolver.failed)return console.warn(`Section solver failed for node ${this.currentSection.centerNodeId}. Error: ${this.sectionSolver.error}`),this.stats.failedSectionSolvers++,this.stats.failedOptimizations++,this.sectionSolver=null,void(this.activeSubSolver=null);if(this.sectionSolver.solved){const t=this.sectionSolver.sectionConnectionTerminals,e=this.sectionSolver.sectionNodes,n=this.sectionSolver.centerNodeId;if(this.sectionSolver=null,this.activeSubSolver=null,!t)return void console.warn(`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`);const s=new Set(e.map(t=>t.capacityMeshNodeId)),o=Vl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:s}),i=new Map(this.usedNodeCapacityMap),r=t;for(const t of r){const e=this.connectionsWithNodes.find(e=>e.connection.name===t.connectionName);if(e?.path)for(const t of e.path)if(s.has(t.capacityMeshNodeId)){const e=i.get(t.capacityMeshNodeId)??0;i.set(t.capacityMeshNodeId,Math.max(0,e-1))}}for(const t of r)if(t.path)for(const e of t.path)s.has(e.capacityMeshNodeId)&&i.set(e.capacityMeshNodeId,(i.get(e.capacityMeshNodeId)??0)+1);Vl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:i,nodeMap:this.nodeMap,sectionNodeIds:s})>o?(this.stats.successfulOptimizations++,this._mergeSolvedSectionPaths({centerNodeId:n,sectionConnectionTerminals:t}),this._recalculateNodeCapacityUsage()):this.stats.failedOptimizations++}}_mergeSolvedSectionPaths({centerNodeId:t,sectionConnectionTerminals:e}){for(const n of e){if(!n.path){console.warn(`No path found for connection ${n.connectionName} in section ${t}`);continue}const e=this.connectionsWithNodes.find(t=>t.connection.name===n.connectionName);if(!e||!e.path){console.warn(`Original connection or path not found for ${n.connectionName} while merging section ${t}`);continue}const s=e.path,o=n.path,i=s.findIndex(t=>t.capacityMeshNodeId===n.startNodeId),r=s.findIndex(t=>t.capacityMeshNodeId===n.endNodeId);if(-1===i||-1===r){console.warn(`Could not find start/end nodes (${n.startNodeId}/${n.endNodeId}) in original path for ${n.connectionName}`);continue}const[a,c]=i<=r?[i,r]:[r,i],h=s.slice(0,a),l=s.slice(c+1);let d=o;if(o.length>0&&s[a]&&o[0].capacityMeshNodeId!==s[a].capacityMeshNodeId){if(o[o.length-1].capacityMeshNodeId!==s[a].capacityMeshNodeId){console.warn(`New section path for ${n.connectionName} doesn't align with original path boundaries. Skipping merge for this connection.`);continue}d=[...o].reverse()}e.path=[...h,...d,...l]}}_recalculateNodeCapacityUsage(){this.usedNodeCapacityMap.clear();for(const t of this.connectionsWithNodes)if(t.path)for(const e of t.path)this.usedNodeCapacityMap.set(e.capacityMeshNodeId,(this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0)+1);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s)}}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}_step(){this.iterations>=this.MAX_ITERATIONS-1?this.solved=!0:"initialization"===this.stage?this._stepInitialization():"section-optimization"===this.stage&&this._stepSectionOptimization()}visualize(){const t=this.connectionsWithNodes.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connection.name,path:t.path}));return Gl({nodeMap:this.nodeMap,sectionConnectionTerminals:this.connectionsWithNodes.map(t=>({connectionName:t.connection.name,startNodeId:t.path?.[0]?.capacityMeshNodeId,endNodeId:t.path?.[t.path.length-1]?.capacityMeshNodeId})),completedPaths:t,sectionNodes:this.nodes,sectionEdges:this.edges,colorMap:this.colorMap,totalCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeOpacity:.05,title:"Capacity Pathing Multi-Section Solver (Solved)"})}},nd=class extends Ln{getSolverName(){return"DeadEndSolver"}removedNodeIds;targetNodeIds;leaves;leavesIndex;adjacencyList;nodeMap;nodes;edges;constructor({nodes:t,edges:e}){super(),this.MAX_ITERATIONS=t.length,this.nodes=t,this.edges=e,this.removedNodeIds=new Set,this.targetNodeIds=new Set(t.filter(t=>t._containsTarget).map(t=>t.capacityMeshNodeId)),this.adjacencyList=new Map(t.map(({capacityMeshNodeId:t})=>[t,new Set]));for(const{nodeIds:[t,n]}of e)this.adjacencyList.get(t).add(n),this.adjacencyList.get(n).add(t);this.leavesIndex=0,this.leaves=[...this.adjacencyList.entries()].filter(([t,e])=>1===e.size).filter(([t,e])=>!this.targetNodeIds.has(t)).map(([t,e])=>t)}_step(){if(this.leavesIndex===this.leaves.length)return void(this.solved=!0);const t=this.leaves[this.leavesIndex],e=this.adjacencyList.get(t);if(!e||0===e.size)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));const[n]=e,s=n?this.adjacencyList.get(n):void 0;if(!n||!s)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));s.delete(t),this.removedNodeIds.add(t),this.adjacencyList.delete(t),1!==s.size||this.targetNodeIds.has(n)||this.leaves.push(n),this.leavesIndex+=1,this.leavesIndex===this.leaves.length&&(this.solved=!0)}visualize(){if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const o=Math.min(...n.availableZ),i=Math.min(...s.availableZ),r={x:n.center.x+o*n.width*.05,y:n.center.y-o*n.width*.05},a={x:s.center.x+i*s.width*.05,y:s.center.y-i*s.width*.05},c=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${c.join(",")}`,points:[r,a],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5",strokeColor:t.nodeIds.some(t=>this.removedNodeIds.has(t))?Nn("black",.9):void 0})}}return e}},sd=class extends Kh{getSolverName(){return"NoOffBoardMultipleHighDensityRouteStitchSolver"}constructor(t){super(t),this.unsolvedRoutes=[];const e=new Map;for(const n of t.hdRoutes){const t=e.get(n.connectionName)||[];t.push(n),e.set(n.connectionName,t)}for(const[n,s]of e.entries()){const e=t.connections.find(t=>t.name===n);if(!e)continue;const o={...e.pointsToConnect[0],z:wn(Cn(e.pointsToConnect[0]),t.layerCount)},i={...e.pointsToConnect[1],z:wn(Cn(e.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:n,hdRoutes:s,start:o,end:i})}for(const n of t.connections)e.has(n.name)||this.unsolvedRoutes.push({connectionName:n.name,hdRoutes:[],start:{...n.pointsToConnect[0],z:wn(Cn(n.pointsToConnect[0]),t.layerCount)},end:{...n.pointsToConnect[1],z:wn(Cn(n.pointsToConnect[1]),t.layerCount)}})}},od=.005,id=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]);e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new kn(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Yn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){return this.getAdjacentSameLayerUnprocessedNodes2(t)}getAdjacentSameLayerUnprocessedNodes2(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<od&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<od&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<od&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<od&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Same Layer Node Merger"};for(const e of this.newNodes)t.rects.push(Xl(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=Xl(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=Xl(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},rd=class extends Ln{getSolverName(){return"StrawSolver"}multiLayerNodes;strawNodes;skippedNodes;unprocessedNodes;strawSize;nodeIdCounter;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.strawSize=t.strawSize??.5,this.multiLayerNodes=[],this.strawNodes=[],this.skippedNodes=[],this.nodeIdCounter=0,this.unprocessedNodes=[];for(const e of t.nodes)1===e.availableZ.length?this.unprocessedNodes.push(e):this.multiLayerNodes.push(e)}getCapacityOfMultiLayerNodesWithinBounds(t){let e=0;for(const n of this.multiLayerNodes){const s=n.center.x-n.width/2,o=n.center.x+n.width/2,i=n.center.y-n.height/2,r=n.center.y+n.height/2,a=Math.max(t.minX,s),c=Math.min(t.maxX,o),h=Math.max(t.minY,i),l=Math.min(t.maxY,r);if(a<c&&h<l){const t=(c-a)*(l-h)/(n.width*n.height);e+=xh(n)*t}}return e}getSurroundingCapacities(t){const e=Math.min(t.width,t.height);return{leftSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2-e,maxX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),rightSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x+t.width/2,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),topSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2-e,maxY:t.center.y-t.height/2}),bottomSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y+t.height/2,maxY:t.center.y+t.height/2+e})}}createStrawsForNode(t){const e=[],{leftSurroundingCapacity:n,rightSurroundingCapacity:s,topSurroundingCapacity:o,bottomSurroundingCapacity:i}=this.getSurroundingCapacities(t);if(1*(n+s)>o+i){const n=Math.floor(t.height/this.strawSize),s=t.height/n;for(let o=0;o<n;o++){const n=t.center.y-t.height/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:t.center.x,y:n},width:t.width,height:s,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}else{const n=Math.floor(t.width/this.strawSize),s=t.width/n;for(let o=0;o<n;o++){const n=t.center.x-t.width/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:n,y:t.center.y},width:s,height:t.height,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}return e}getResultNodes(){return[...this.multiLayerNodes,...this.strawNodes,...this.skippedNodes]}_step(){const t=this.unprocessedNodes.pop();if(!t)return void(this.solved=!0);if(t.width<this.strawSize&&t.height<this.strawSize)return void this.skippedNodes.push(t);if(t._containsTarget)return void this.skippedNodes.push(t);const e=this.createStrawsForNode(t);this.strawNodes.push(...e),0===e.length&&this.strawNodes.push(t)}visualize(){const t={rects:[],lines:[],points:[],circles:[],title:"Straw Solver"};for(const e of this.unprocessedNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(200, 200, 200, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nUnprocessed\n${e.width}x${e.height}`});for(const e of this.strawNodes){const n=0===e.availableZ[0]?"rgba(0, 150, 255, 0.5)":"rgba(255, 100, 0, 0.5)";t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nLayer: ${e.availableZ[0]}\n${e.width}x${e.height}`,layer:`z${e.availableZ.join(",")}`})}for(const e of this.multiLayerNodes)t.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,fill:"rgba(100, 255, 100, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",layer:`z${e.availableZ.join(",")}`,label:`${e.capacityMeshNodeId}\nLayers: ${e.availableZ.join(",")}\n${e.width}x${e.height}`});return t}};function ad(t){const{nodeId:e,nodeIdToSegmentIds:n,segmentIdToNodeIds:s,hops:o}=t;if(0===o)return[e];const i=new Set([e]),r=[{nodeId:e,remainingHops:o}];for(;r.length>0;){const{nodeId:t,remainingHops:e}=r.shift();if(0===e)continue;const o=n.get(t)||[];for(const t of o){const n=s.get(t)||[];for(const t of n)i.has(t)||(i.add(t),r.push({nodeId:t,remainingHops:e-1}))}}return Array.from(i)}var cd=t=>Array.from(t.entries()).map(([t,{x:e,y:n,z:s}])=>`${t}(${e?.toFixed(3)??""},${n?.toFixed(3)??""},${s??""})`).sort().join("&"),hd=(t,e,n,s)=>{const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s);return o<=Math.max(n,s)&&i>=r},ld=(t,e,n,s)=>{const o=[],i=new Map(t.originalPointMap);for(const[t,e]of n.entries()){const n=i.get(t);i.set(t,{x:e.x??n.x,y:e.y??n.y,z:e.z??n.z})}for(const n of t.allNodeIds){if(!e.get(n))continue;const r=t.segmentPairsInNode.get(n);for(const t of r){const e=i.get(t[0]),s=i.get(t[1]);e.z!==s.z&&o.push({type:"transition_via",segmentPoints:t,capacityMeshNodeId:n,probabilityOfFailure:0})}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){if(s?.areIdsConnected(r[t][0],r[t][1]))continue;const a=r[t],c=r[e],h=i.get(a[0]),l=i.get(a[1]),d=i.get(c[0]),u=i.get(c[1]);if(!hd(h.z,l.z,d.z,u.z))continue;const p=D(h,l,d,u),f=h.z===l.z&&d.z===u.z&&h.z===d.z;p&&(f?o.push({type:"same_layer_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}):h.z===l.z&&d.z!==u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:a,transitionCrossingLine:c,probabilityOfFailure:0}):h.z!==l.z&&d.z===u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:c,transitionCrossingLine:a,probabilityOfFailure:0}):h.z!==l.z&&d.z!==u.z&&o.push({type:"double_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}))}}return o},dd=(t,e,n)=>{if("change_layer"===e.type)for(const n of e.segmentPointIds){const s=t.get(n)||{};t.set(n,{...s,z:e.newZ})}else if("swap_position_on_segment"===e.type){const[s,o]=e.segmentPointIds,i=n(s),r=n(o),a=t.get(s)||{},c=t.get(o)||{};t.set(s,{...a,x:r.x,y:r.y}),t.set(o,{...c,x:i.x,y:i.y})}else if("combined"===e.type)for(const s of e.operations)dd(t,s,n)},ud=(t,e)=>{const n=new Map,s=new Map,o=new Map,i=[];let r=0;for(const a of t)for(const t of a.assignedPoints){const c={segmentPointId:"SP"+r++,segmentId:a.nodePortSegmentId,capacityMeshNodeIds:e.get(a.nodePortSegmentId),connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,x:t.point.x,y:t.point.y,z:t.point.z,directlyConnectedSegmentPointIds:[]};n.set(c.segmentPointId,c);for(const t of c.capacityMeshNodeIds)s.set(t,[...s.get(t)??[],c.segmentPointId]);o.set(a.nodePortSegmentId,[...o.get(a.nodePortSegmentId)??[],c.segmentPointId]),i.push(c)}return{segmentPointMap:n,nodeToSegmentPointMap:s,segmentToSegmentPointMap:o}},pd=class extends Ln{getSolverName(){return"UnravelSectionSolver"}nodeMap;dedupedSegments;dedupedSegmentMap;MUTABLE_HOPS=1;unravelSection;candidates=[];lastProcessedCandidate=null;bestCandidate=null;originalCandidate;rootNodeId;nodeIdToSegmentIds;segmentIdToNodeIds;colorMap;tunedNodeCapacityMap;MAX_CANDIDATES=500;iterationsSinceImprovement=0;hyperParameters;selectedCandidateIndex=null;queuedOrExploredCandidatePointModificationHashes=new Set;constructorParams;constructor(t){if(super(),this.constructorParams=t,this.MUTABLE_HOPS=t.MUTABLE_HOPS??this.MUTABLE_HOPS,this.MAX_ITERATIONS=5e4,this.hyperParameters={...t.hyperParameters,MAX_ITERATIONS_WITHOUT_IMPROVEMENT:200},this.nodeMap=t.nodeMap,this.dedupedSegments=t.dedupedSegments,t.dedupedSegmentMap)this.dedupedSegmentMap=t.dedupedSegmentMap;else{this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t)}this.nodeIdToSegmentIds=t.nodeIdToSegmentIds,this.segmentIdToNodeIds=t.segmentIdToNodeIds,this.rootNodeId=t.rootNodeId,this.colorMap=t.colorMap??{},this.unravelSection=this.createUnravelSection({segmentPointMap:t.segmentPointMap,nodeToSegmentPointMap:t.nodeToSegmentPointMap,segmentToSegmentPointMap:t.segmentToSegmentPointMap}),this.tunedNodeCapacityMap=new Map;for(const t of this.unravelSection.allNodeIds)this.tunedNodeCapacityMap.set(t,xh(this.nodeMap.get(t)));this.originalCandidate=this.createInitialCandidate(),this.candidates=[this.originalCandidate]}getConstructorParams(){return{...this.constructorParams,segmentPointMap:this.unravelSection.segmentPointMap,nodeToSegmentPointMap:this.unravelSection.segmentPointsInNode,segmentToSegmentPointMap:this.unravelSection.segmentPointsInSegment}}createUnravelSection(t){const e=ad({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS}),n=ad({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS+1}),s=Array.from(new Set(n).difference(new Set(e)));t?.segmentPointMap||(t=ud(this.dedupedSegments,this.segmentIdToNodeIds));const o=new Map;for(const e of n)o.set(e,t.nodeToSegmentPointMap.get(e));const i=new Map;for(const e of n)for(const n of o.get(e)){const e=t.segmentPointMap.get(n);i.set(n,e)}const r=Array.from(i.values()),a=new Map;for(const t of r)a.set(t.segmentId,[...a.get(t.segmentId)??[],t.segmentPointId]);for(const[e,n]of o.entries())for(let e=0;e<n.length;e++){const s=t.segmentPointMap.get(n[e]);for(let o=e+1;o<n.length;o++){const e=t.segmentPointMap.get(n[o]);e.segmentPointId!==s.segmentPointId&&(e.segmentId!==s.segmentId&&e.connectionName===s.connectionName&&(e.directlyConnectedSegmentPointIds.includes(s.segmentPointId)||(s.directlyConnectedSegmentPointIds.push(e.segmentPointId),e.directlyConnectedSegmentPointIds.push(s.segmentPointId))))}}const c=new Map;for(const t of n)c.set(t,[]);for(const e of r)for(const n of e.capacityMeshNodeIds){const s=c.get(n);if(s)for(const o of e.directlyConnectedSegmentPointIds){const i=t.segmentPointMap.get(o);i.segmentPointId!==e.segmentPointId&&(i.capacityMeshNodeIds.some(t=>t===n)&&(s.some(([t,n])=>t===e.segmentPointId&&n===i.segmentPointId||t===i.segmentPointId&&n===e.segmentPointId)||s.push([e.segmentPointId,i.segmentPointId])))}}const h=new Set;for(const t of e)for(const e of this.nodeIdToSegmentIds.get(t)){this.segmentIdToNodeIds.get(e).every(t=>!this.nodeMap.get(t)._containsTarget)&&h.add(e)}const l=new Set;for(const t of r){const n=t.capacityMeshNodeIds.some(t=>e.includes(t)),s=this.dedupedSegmentMap.get(t.segmentId),o=s&&s.availableZ.length>1;(n||o)&&l.add(t.segmentPointId)}const d=new Set;for(const t of r){if(t.capacityMeshNodeIds.some(t=>this.nodeMap.get(t)?._containsTarget)){const e=this.dedupedSegmentMap.get(t.segmentId);e&&1===e.availableZ.length&&d.add(t.segmentPointId)}}return{allNodeIds:n,mutableNodeIds:e,immutableNodeIds:s,mutableSegmentIds:h,segmentPairsInNode:c,segmentPointMap:i,segmentPointsInNode:o,segmentPointsInSegment:a,originalPointMap:i,mutableSegmentPointIds:l,zLockedSegmentPointIds:d}}createInitialCandidate(){const t=new Map,e=ld(this.unravelSection,this.nodeMap,t),n=this.computeG({issues:e,originalCandidate:{},operationsPerformed:0,operation:{}});return{pointModifications:t,g:n,h:0,f:n,operationsPerformed:0,candidateHash:cd(t),issues:ld(this.unravelSection,this.nodeMap,t)}}get nextCandidate(){return this.candidates[0]??null}getPointInCandidate(t,e){const n=this.unravelSection.segmentPointMap.get(e),s=t.pointModifications.get(e);return{x:s?.x??n.x,y:s?.y??n.y,z:s?.z??n.z,segmentId:n.segmentId}}getConnectionSegmentPointIds(t){const e=[];for(const[n,s]of this.unravelSection.segmentPointMap.entries())s.connectionName===t&&e.push(n);return e}canConnectionUseLayer(t,e){for(const n of t){const t=this.unravelSection.segmentPointMap.get(n),s=this.dedupedSegmentMap.get(t.segmentId);if(!s||!s.availableZ.includes(e))return!1}return!0}getOperationsForIssue(t,e){const n=[];if("transition_via"===e.type){const[s,o]=e.segmentPoints,i=this.getPointInCandidate(t,s),r=this.getPointInCandidate(t,o),a=this.unravelSection.segmentPointMap.get(s),c=(this.unravelSection.segmentPointMap.get(o),this.dedupedSegmentMap.get(i.segmentId).availableZ),h=this.dedupedSegmentMap.get(r.segmentId).availableZ,l=this.unravelSection.zLockedSegmentPointIds.has(s),d=this.unravelSection.zLockedSegmentPointIds.has(o),u=this.getConnectionSegmentPointIds(a.connectionName);if(this.canConnectionUseLayer(u,r.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:t})}if(this.canConnectionUseLayer(u,i.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:t})}this.unravelSection.mutableSegmentPointIds.has(s)&&!l&&c.includes(r.z)&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:[s]}),this.unravelSection.mutableSegmentPointIds.has(o)&&!d&&h.includes(i.z)&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:[o]})}if("same_layer_crossing"===e.type){const[t,s]=e.crossingLine1,[o,i]=e.crossingLine2,r=[],a=this.unravelSection.segmentPointMap.get(t),c=this.unravelSection.segmentPointMap.get(s),h=this.unravelSection.segmentPointMap.get(o),l=this.unravelSection.segmentPointMap.get(i),d=this.unravelSection.mutableSegmentPointIds.has(t),u=this.unravelSection.mutableSegmentPointIds.has(s),p=this.unravelSection.mutableSegmentPointIds.has(o),f=this.unravelSection.mutableSegmentPointIds.has(i),m=this.unravelSection.zLockedSegmentPointIds.has(t),g=this.unravelSection.zLockedSegmentPointIds.has(s),y=this.unravelSection.zLockedSegmentPointIds.has(o),x=this.unravelSection.zLockedSegmentPointIds.has(i);d&&p&&a.segmentId===h.segmentId&&r.push([t,o]),d&&f&&a.segmentId===l.segmentId&&r.push([t,i]),u&&p&&c.segmentId===h.segmentId&&r.push([s,o]),u&&f&&c.segmentId===l.segmentId&&r.push([s,i]);for(const[t,e]of r)n.push({type:"swap_position_on_segment",segmentPointIds:[t,e]});const v=this.getConnectionSegmentPointIds(a.connectionName),b=this.getConnectionSegmentPointIds(h.connectionName),P=new Set;for(const t of this.unravelSection.segmentPointMap.values()){const e=this.dedupedSegmentMap.get(t.segmentId);if(e)for(const t of e.availableZ)P.add(t)}for(const t of P)if(t!==a.z&&this.canConnectionUseLayer(v,t)){const e=v.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}for(const t of P)if(t!==h.z&&this.canConnectionUseLayer(b,t)){const e=b.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}const S=this.dedupedSegmentMap.get(a.segmentId),M=this.dedupedSegmentMap.get(c.segmentId),N=this.dedupedSegmentMap.get(h.segmentId),I=this.dedupedSegmentMap.get(l.segmentId),_=(t,e)=>t.every(t=>t.availableZ.includes(e));if(d&&u&&!m&&!g){const e=0===a.z?1:0;_([S,M],e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t,s]})}if(p&&f&&!y&&!x){const t=0===h.z?1:0;_([N,I],t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o,i]})}if(d&&!m){const e=0===a.z?1:0;S.availableZ.includes(e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t]})}if(u&&!g){const t=0===c.z?1:0;M.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[s]})}if(p&&!y){const t=0===h.z?1:0;N.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o]})}if(f&&!x){const t=0===l.z?1:0;I.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i]})}}return n}computeG(t){const{issues:e,originalCandidate:n,operationsPerformed:s,operation:o}=t,i=new Map;for(const t of e){i.has(t.capacityMeshNodeId)||i.set(t.capacityMeshNodeId,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0});const e=i.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"===t.type||"single_transition_crossing"===t.type?e.numEntryExitLayerChanges++:t.type}let r=0;for(const[t,{numEntryExitLayerChanges:e,numSameLayerCrossings:n,numTransitionCrossings:s}]of i){const o=this.nodeMap.get(t),i=Math.min(bh(o,n,e,s),.999999);r+=Math.log(1-i)}var a;return(a=r)<-Math.LN2?Math.log(1-Math.exp(a)):Math.log(-Math.expm1(a))}getUnexploredNeighborByApplyingOperation(t,e){const n=new Map(t.pointModifications);dd(n,e,e=>this.getPointInCandidate(t,e));const s=cd(n);if(this.queuedOrExploredCandidatePointModificationHashes.has(s))return null;const o=ld(this.unravelSection,this.nodeMap,n),i=t.operationsPerformed+1,r=this.computeG({issues:o,originalCandidate:t,operationsPerformed:i,operation:e});return{issues:o,g:r,h:0,f:r,pointModifications:n,candidateHash:s,operationsPerformed:i}}getNeighborOperationsForCandidate(t){return t.issues.flatMap(e=>this.getOperationsForIssue(t,e))}getNeighbors(t){const e=[],n=this.getNeighborOperationsForCandidate(t);for(const s of n){const n=this.getUnexploredNeighborByApplyingOperation(t,s);n&&e.push(n)}return e}_step(){const t=this.candidates.shift();this.iterationsSinceImprovement++,this.iterationsSinceImprovement>this.hyperParameters.MAX_ITERATIONS_WITHOUT_IMPROVEMENT?this.solved=!0:t?(this.lastProcessedCandidate=t,t.f<(this.bestCandidate?.f??1/0)&&(this.bestCandidate=t,this.iterationsSinceImprovement=0),this.getNeighbors(t).forEach(t=>{this.queuedOrExploredCandidatePointModificationHashes.has(t.candidateHash)||(this.queuedOrExploredCandidatePointModificationHashes.add(t.candidateHash),this.candidates.push(t))}),this.candidates.sort((t,e)=>t.f-e.f),this.candidates.length=Math.min(this.candidates.length,this.MAX_CANDIDATES)):this.solved=!0}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Section Solver"};let e=null;if(e=null!==this.selectedCandidateIndex?"best"===this.selectedCandidateIndex?this.bestCandidate:"original"===this.selectedCandidateIndex?this.originalCandidate:this.candidates[this.selectedCandidateIndex]:this.solved?this.bestCandidate:this.lastProcessedCandidate||this.candidates[0],!e)return t;const n=new Map;for(const[t,s]of this.unravelSection.segmentPointMap){const o={...s},i=e.pointModifications.get(t);i&&(void 0!==i.x&&(o.x=i.x),void 0!==i.y&&(o.y=i.y),void 0!==i.z&&(o.z=i.z)),n.set(t,o)}for(const[e,s]of n)t.points.push({x:s.x,y:s.y,label:`${e}\nSegment: ${s.segmentId} ${this.unravelSection.mutableSegmentIds.has(s.segmentId)?"MUTABLE":"IMMUTABLE"}\nLayer: ${s.z}`,color:this.colorMap[s.connectionName]||"#000"});const s=new Map;for(const t of this.unravelSection.allNodeIds)s.set(t,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0,estPf:0});for(const t of e.issues){const e=s.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"!==t.type&&"single_transition_crossing"!==t.type||e.numEntryExitLayerChanges++}for(const[t,e]of s.entries()){const n=this.nodeMap.get(t);e.estPf=bh(n,e.numSameLayerCrossings,e.numEntryExitLayerChanges,e.numTransitionCrossings)}for(const e of this.unravelSection.allNodeIds){const n=this.nodeMap.get(e),o=this.unravelSection.mutableNodeIds.includes(e),i=s.get(e),r=[`${e} (${o?"MUT":"IMM"})`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${i.estPf.toFixed(3)}`,`TC: ${i.numTransitionCrossings}`,`SLC: ${i.numSameLayerCrossings}`,`EELC: ${i.numEntryExitLayerChanges}`].join("\n");t.rects.push({center:n.center,label:r,color:o?"green":"red",width:n.width/8,height:n.height/8})}for(const[e,s]of this.unravelSection.segmentPointsInSegment){if(s.length<=1)continue;const o=s.map(t=>n.get(t));for(let n=0;n<o.length-1;n++)t.lines.push({points:[{x:o[n].x,y:o[n].y},{x:o[n+1].x,y:o[n+1].y}],strokeColor:this.colorMap[e]||"#000"})}for(const[e,s]of n)for(const o of s.directlyConnectedSegmentPointIds)if(e<o){const e=n.get(o);if(!e)continue;const i=s.z===e.z,r=s.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:s.x,y:s.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[s.connectionName]||"#000"})}for(const s of e.issues){const e=this.nodeMap.get(s.capacityMeshNodeId);if("transition_via"===s.type)for(const o of s.segmentPoints){const s=n.get(o);t.circles.push({center:{x:s.x,y:s.y},radius:e.width/16,stroke:"#ff0000",fill:"rgba(255, 0, 0, 0.2)",label:`Via Issue\n${o}\nLayer: ${s.z}`})}else if("same_layer_crossing"===s.type)for(const[o,i]of[s.crossingLine1,s.crossingLine2]){const s=n.get(o),r=n.get(i);t.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:"rgba(255,0,0,0.2)",strokeWidth:e.width/32})}}for(const[s,o]of e.pointModifications){const e=n.get(s),o=this.unravelSection.segmentPointMap.get(s);t.circles.push({center:{x:e.x,y:e.y},radius:.05,stroke:"#0000ff",fill:"rgba(0, 0, 255, 0.2)",label:`${s}\nOriginal: (${o.x.toFixed(2)}, ${o.y.toFixed(2)}, ${o.z})\nNew: (${e.x.toFixed(2)}, ${e.y.toFixed(2)}, ${e.z})`})}return t}};import fd from"object-hash";var md=t=>(Math.round(20*t)/20).toFixed(2),gd=t=>(Math.round(1e3*t)/1e3).toFixed(3);Me();var yd=class extends pd{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Pe():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}computeCacheKeyAndTransform(){const t=this.nodeMap.get(this.rootNodeId),e=y(-t.center.x,-t.center.y),n=new Map,s=new Map,o=new Map,i=new Map,r=new Map,a=new Map;let c=0,h=0,l=0;const d=[...this.unravelSection.allNodeIds].sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.center.x!==s.center.x?n.center.x-s.center.x:n.center.y-s.center.y});for(const t of d){const e="node_"+c++;n.set(t,e),s.set(e,t)}const u=[...Array.from(this.unravelSection.segmentPointMap.entries()).sort(([,t],[,e])=>t.x!==e.x?t.x-e.x:t.y-e.y).map(([t])=>t)].sort();for(const t of u){const e="sp_"+l++;r.set(t,e),a.set(e,t);const n=this.unravelSection.segmentPointMap.get(t).segmentId;if(!o.has(n)){const t="seg_"+h++;o.set(n,t),i.set(t,n)}}const p={};for(const[t,s]of n.entries()){const n=this.nodeMap.get(t),o=g(e,n.center);p[s]={width:n.width,height:n.height,availableZ:n.availableZ,center:{x:md(o.x),y:md(o.y)}}}const f={};for(const[t,n]of r.entries()){const s=this.unravelSection.segmentPointMap.get(t),o=g(e,{x:s.x,y:s.y});f[n]={x:md(o.x),y:md(o.y),z:s.z}}const m={hyperParameters:this.hyperParameters,normalizedNodes:p,normalizedSegmentPoints:f,mutableHops:this.MUTABLE_HOPS},x=`unravelsec:${fd(m)}`,v={realToCacheTransform:e,nodeIdMap:n,segmentIdMap:o,segmentPointIdMap:r,reverseNodeIdMap:s,reverseSegmentIdMap:i,reverseSegmentPointIdMap:a};return this.cacheKey=x,this.cacheToSolveSpaceTransform=v,{cacheKey:x,cacheToSolveSpaceTransform:v}}applyCachedSolution(t){if(!1===t.success)return void(this.failed=!0);if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available to apply cached solution.");const{reverseSegmentPointIdMap:e,reverseNodeIdMap:n}=this.cacheToSolveSpaceTransform,s=new Map;for(const[n,o]of t.bestCandidatePointModificationsDelta){const t=e.get(n);if(!t){console.warn(`Could not find original ID for normalized SP ID: ${n} when applying cache.`);continue}const i=this.unravelSection.segmentPointMap.get(t);if(!i){console.warn(`Could not find original segment point for ID: ${t} when applying cache.`);continue}const r={};if(void 0!==o.dx){const t=parseFloat(o.dx);Number.isNaN(t)?console.warn(`Failed to parse cached dx coordinate: ${o.dx}`):r.x=i.x+t}if(void 0!==o.dy){const t=parseFloat(o.dy);Number.isNaN(t)?console.warn(`Failed to parse cached dy coordinate: ${o.dy}`):r.y=i.y+t}void 0!==o.dz&&(r.z=i.z+o.dz),Object.keys(r).length>0&&s.set(t,r)}const o=ld(this.unravelSection,this.nodeMap,s);this.bestCandidate={pointModifications:s,issues:o,f:t.bestCandidateF,g:t.bestCandidateF,h:0,operationsPerformed:-1,candidateHash:cd(s)},this.cacheHit=!0,this.solved=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(this.failed)return void this.cacheProvider?.setCachedSolutionSync(this.cacheKey,{success:!1});if(!this.bestCandidate)return;const{segmentPointIdMap:t}=this.cacheToSolveSpaceTransform,e=[];for(const[n,s]of this.bestCandidate.pointModifications.entries()){const o=t.get(n);if(!o){console.warn(`Could not find normalized ID for original SP ID: ${n} when saving to cache.`);continue}const i=this.unravelSection.segmentPointMap.get(n);if(!i){console.warn(`Could not find original segment point for ID: ${n} when saving cache.`);continue}const r={};let a=!1;if(void 0!==s.x){const t=s.x-i.x,e=gd(t);0!==parseFloat(e)&&(r.dx=e,a=!0)}if(void 0!==s.y){const t=s.y-i.y,e=gd(t);0!==parseFloat(e)&&(r.dy=e,a=!0)}if(void 0!==s.z){const t=s.z-i.z;0!==t&&(r.dz=t,a=!0)}a&&e.push([o,r])}const n={success:!0,bestCandidatePointModificationsDelta:e,bestCandidateF:this.bestCandidate.f};this.cacheProvider?.setCachedSolutionSync(this.cacheKey,n)}},xd=class extends Ln{getSolverName(){return"UnravelMultiSectionSolver"}nodeMap;dedupedSegmentMap;dedupedSegments;nodeIdToSegmentIds;segmentIdToNodeIds;nodeToSegmentPointMap;segmentToSegmentPointMap;colorMap;tunedNodeCapacityMap;MAX_NODE_ATTEMPTS=2;MUTABLE_HOPS=1;ACCEPTABLE_PF=.05;MAX_ITERATIONS_WITHOUT_IMPROVEMENT=200;nodePfMap;attemptsToFixNode;activeSubSolver=null;segmentPointMap;cacheProvider=null;constructor({assignedSegments:t,colorMap:e,nodes:n,cacheProvider:s}){super(),this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.cacheHits=0,this.stats.cacheMisses=0,this.cacheProvider=s??null,this.MAX_ITERATIONS=1e6,this.dedupedSegments=(t=>{const e=[],n=new Map;let s=-1;for(const o of t){const t=`${o.start.x}-${o.start.y}-${o.end.x}-${o.end.y}-${o.availableZ.join(",")}`,i=n.get(t);i?o.nodePortSegmentId=i.nodePortSegmentId:(s++,o.nodePortSegmentId=`SEG${s}`,n.set(t,o),e.push(o))}return e})(t),this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t);this.nodeMap=new Map;for(const t of n)this.nodeMap.set(t.capacityMeshNodeId,t);this.nodeIdToSegmentIds=new Map,this.segmentIdToNodeIds=new Map,this.attemptsToFixNode=new Map;for(const e of t)this.segmentIdToNodeIds.set(e.nodePortSegmentId,[...this.segmentIdToNodeIds.get(e.nodePortSegmentId)??[],e.capacityMeshNodeId]),this.nodeIdToSegmentIds.set(e.capacityMeshNodeId,[...this.nodeIdToSegmentIds.get(e.capacityMeshNodeId)??[],e.nodePortSegmentId]);this.colorMap=e??{},this.tunedNodeCapacityMap=new Map;for(const[t,e]of this.nodeMap)this.tunedNodeCapacityMap.set(t,xh(e));const{segmentPointMap:o,nodeToSegmentPointMap:i,segmentToSegmentPointMap:r}=ud(this.dedupedSegments,this.segmentIdToNodeIds);this.segmentPointMap=o,this.nodeToSegmentPointMap=i,this.segmentToSegmentPointMap=r,this.nodePfMap=this.computeInitialPfMap()}computeInitialPfMap(){const t=new Map;for(const[e,n]of this.nodeMap.entries())t.set(e,this.computeNodePf(n));return t}computeNodePf(t){const{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}=(t=>{let e=0,n=0,s=0;const o=new Map;for(const e of t)o.has(e.connectionName)||o.set(e.connectionName,[]),o.get(e.connectionName).push(e);const i=[],r=[];for(const[t,e]of o.entries()){if(e.length<2)continue;const s=e[0];for(let o=1;o<e.length;o++){const a=e[o],c={connectionName:t,z:s.z,points:[s,a]};s.z!==a.z?(n++,r.push({connectionName:t,points:[s,a]})):i.push(c)}}for(let t=0;t<i.length;t++)for(let n=t+1;n<i.length;n++){const s=i[t],o=i[n];s.z===o.z&&D(s.points[0],s.points[1],o.points[0],o.points[1])&&e++}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){const n=r[t],o=r[e];D(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}for(let t=0;t<r.length;t++)for(let e=0;e<i.length;e++){const n=r[t],o=i[e];D(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}})((this.nodeToSegmentPointMap.get(t.capacityMeshNodeId)??[]).map(t=>this.segmentPointMap.get(t)));return bh(t,e,n,s)}_step(){if(this.iterations>=this.MAX_ITERATIONS-1)return void(this.solved=!0);if(!this.activeSubSolver){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_NODE_ATTEMPTS)>e&&(e=s,t=n)}if(!t||e<this.ACCEPTABLE_PF)return void(this.solved=!0);this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.activeSubSolver=new yd({dedupedSegments:this.dedupedSegments,dedupedSegmentMap:this.dedupedSegmentMap,nodeMap:this.nodeMap,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,colorMap:this.colorMap,rootNodeId:t,MUTABLE_HOPS:this.MUTABLE_HOPS,segmentPointMap:this.segmentPointMap,nodeToSegmentPointMap:this.nodeToSegmentPointMap,segmentToSegmentPointMap:this.segmentToSegmentPointMap,cacheProvider:this.cacheProvider})}this.activeSubSolver.step();const{bestCandidate:t,originalCandidate:e,lastProcessedCandidate:n}=this.activeSubSolver;if(this.activeSubSolver.failed)return this.stats.failedOptimizations+=1,void(this.activeSubSolver=null);if(this.activeSubSolver.solved){this.activeSubSolver.cacheHit?this.stats.cacheHits+=1:this.stats.cacheMisses+=1;if(t&&t.g<e.g){this.stats.successfulOptimizations+=1;for(const[e,n]of t.pointModifications.entries()){const t=this.segmentPointMap.get(e);t.x=n.x??t.x,t.y=n.y??t.y,t.z=n.z??t.z}for(const t of this.activeSubSolver.unravelSection.allNodeIds)this.nodePfMap.set(t,this.computeNodePf(this.nodeMap.get(t)))}else this.stats.failedOptimizations+=1;this.activeSubSolver=null}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Multi Section Solver"};for(const[e,n]of this.nodeMap.entries()){const s=this.nodePfMap.get(e)||0,o=Math.min(s,1),i=`rgb(${Math.floor(255*o)}, ${Math.floor(255*(1-o))}, 0)`;0===(this.attemptsToFixNode.get(e)??0)&&0===o||t.rects.push({center:n.center,label:[e,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${s.toFixed(3)}`].join("\n"),color:i,width:n.width/8,height:n.height/8})}for(const e of this.segmentPointMap.values()){const n=this.dedupedSegmentMap.get(e.segmentId);t.points.push({x:e.x,y:e.y,label:[e.segmentPointId,e.segmentId,`z: ${e.z}`,`segment.availableZ: ${n?.availableZ.join(",")}`].join("\n"),color:this.colorMap[e.connectionName]||"#000"})}const e=new Map;for(const t of this.segmentPointMap.values())e.has(t.segmentId)||e.set(t.segmentId,[]),e.get(t.segmentId).push(t);for(const[n,s]of e.entries()){if(s.length<2)continue;const e=[...s].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y);for(let s=0;s<e.length-1;s++)t.lines.push({points:[{x:e[s].x,y:e[s].y},{x:e[s+1].x,y:e[s+1].y}],strokeColor:this.colorMap[n]||"#000"})}const n=new Set,s=Array.from(this.segmentPointMap.values());for(let e=0;e<s.length;e++){const o=s[e];for(let i=e+1;i<s.length;i++){const e=s[i];if(o.connectionName!==e.connectionName||o.segmentId===e.segmentId)continue;if(o.capacityMeshNodeIds.some(t=>e.capacityMeshNodeIds.includes(t))){const s=`${o.segmentPointId}-${e.segmentPointId}`;if(n.has(s))continue;n.add(s);const i=o.z===e.z,r=o.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:o.x,y:o.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[o.connectionName]||"#666"})}}}return t}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.dedupedSegments){const n=e.nodePortSegmentId;for(const e of this.segmentIdToNodeIds.get(n)){const n=this.nodeMap.get(e);t.has(e)||t.set(e,{capacityMeshNodeId:e,portPoints:[],center:n.center,width:n.width,height:n.height})}}for(const e of this.segmentPointMap.values())for(const n of e.capacityMeshNodeIds){const s=t.get(n);s&&s.portPoints.push({x:e.x,y:e.y,z:e.z,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName})}return Array.from(t.values())}};function vd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var bd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipeline1_OriginalUnravel"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;viaDiameter;minTraceWidth;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[vd("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),vd("nodeSolver",Fl,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),vd("singleLayerNodeMerger",id,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),vd("strawSolver",rd,t=>[{nodes:t.singleLayerNodeMerger?.newNodes}],{onSolved:t=>{t.capacityNodes=t.strawSolver?.getResultNodes()}}),vd("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),vd("deadEndSolver",nd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),vd("initialPathingSolver",Bl,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),vd("pathingOptimizer",ed,t=>[{initialPathingSolver:t.initialPathingSolver,simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,cacheProvider:t.cacheProvider,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),vd("edgeToPortSegmentSolver",wl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.pathingOptimizer?.getCapacityPaths()||[],colorMap:t.colorMap}]),vd("segmentToPointSolver",Yl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),vd("unravelMultiSectionSolver",xd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),vd("highDensityRouteSolver",dh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),vd("highDensityStitchSolver",sd,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),vd("traceSimplificationSolver",Il,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.initialPathingSolver?.visualize(),c=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),l=this.segmentToPointSolver?.visualize(),d=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensityStitchSolver?.visualize(),f=this.traceSimplificationSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,c,h,l,d,u?Bn(y,u):null,p,f,this.solved?Bn(y,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}};function Pd(t){const{pos:e,segments:n,dir:s,keepoutRadius:o}=t;let i=1/0;const r=o/4,a={x:e.x-s.x*r,y:e.y-s.y*r},c={x:e.x+s.x*r,y:e.y+s.y*r};for(const t of n){const e=J(a,c,t.start,t.end);i=Math.min(i,e)}return i}function Sd(t,e,n,s){const o=Md(n,s,t),i=Md(n,s,e),r=Md(t,e,n),a=Md(t,e,s);if((o>0&&i<0||o<0&&i>0)&&(r>0&&a<0||r<0&&a>0))return!0;const c=1e-4;return!!(Math.abs(o)<c&&Nd(n,s,t))||(!!(Math.abs(i)<c&&Nd(n,s,e))||(!!(Math.abs(r)<c&&Nd(t,e,n))||!!(Math.abs(a)<c&&Nd(t,e,s))))}function Md(t,e,n){return(n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y)}function Nd(t,e,n){return n.x>=Math.min(t.x,e.x)-1e-4&&n.x<=Math.max(t.x,e.x)+1e-4&&n.y>=Math.min(t.y,e.y)-1e-4&&n.y<=Math.max(t.y,e.y)+1e-4}function Id(t,e,n){for(const s of n)if(Sd(t,e,s.start,s.end))return!1;return!0}var _d=1e-4;function Cd(t){const e=t.width/2,n=t.height/2,s=t.center.x,o=t.center.y,i={x:s-e,y:o+n},r={x:s+e,y:o+n},a={x:s-e,y:o-n},c={x:s+e,y:o-n};return[{start:i,end:r},{start:r,end:c},{start:c,end:a},{start:a,end:i}]}function Td(t,e,n=.1){const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(0===i)return[];const r=-(o/i),a=s/i,c=n/2;return[{start:{x:t.x+r*c,y:t.y+a*c},end:{x:e.x+r*c,y:e.y+a*c}},{start:{x:t.x-r*c,y:t.y-a*c},end:{x:e.x-r*c,y:e.y-a*c}}]}function Ed(t,e,n){const s=Math.hypot(t.start.x-e.x,t.start.y-e.y),o=Math.hypot(t.end.x-e.x,t.end.y-e.y);if(s<=n||o<=n)return!0;const i=t.end.x-t.start.x,r=t.end.y-t.start.y,a=i*i+r*r;if(0===a)return!1;const c=Math.max(0,Math.min(1,((e.x-t.start.x)*i+(e.y-t.start.y)*r)/a)),h=t.start.x+c*i,l=t.start.y+c*r;return Math.hypot(h-e.x,l-e.y)<=n}function wd(t,e,n){if(!n||0===n.length)return!1;for(const s of n){const n=Math.abs(t.x-s.start.x)<_d&&Math.abs(t.y-s.start.y)<_d&&Math.abs(e.x-s.end.x)<_d&&Math.abs(e.y-s.end.y)<_d,o=Math.abs(t.x-s.end.x)<_d&&Math.abs(t.y-s.end.y)<_d&&Math.abs(e.x-s.start.x)<_d&&Math.abs(e.y-s.start.y)<_d;if(n||o)return!0}return!1}function Rd(t,e,n,s,o){const i=[];for(let r=0;r<t.length-1;r++){const a=t[r],c=t[r+1];wd(a,c,o)||Ed({start:a,end:c},n,s+e)&&i.push(...Td(a,c,e))}return i}var Od=1e-4;function Ad(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=o*a-i*r;if(Math.abs(c)<1e-10)return null;const h=n.x-t.x,l=n.y-t.y,d=(h*a-l*r)/c,u=(h*i-l*o)/c,p=1e-6;return d>p&&d<.999999&&u>p&&u<.999999?{x:t.x+d*o,y:t.y+d*i}:null}function zd(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Od&&Math.abs(t.y-n.start.y)<Od||Math.abs(t.x-n.end.x)<Od&&Math.abs(t.y-n.end.y)<Od)return!0;return!1}function Ld(t,e,n,s){if(!s||0===s.length)return!1;for(let o=e;o<=n;o++)if(o>=0&&o<t.length&&zd(t[o],s))return!0;return!1}var Dd=1e-4,Fd=class extends Ln{constructor(t){super(),this.input=t;const e=t.srj?.layerCount??2;this.input={...t,obstacles:hl(t.obstacles,e)},this.MAX_ITERATIONS=1e6,this.originalHdRoutes=[...this.input.hdRoutes],this.hdRoutes=this.input.hdRoutes,this.KEEPOUT_RADIUS_SCHEDULE=t.keepoutRadiusSchedule??[.3,.5,.5],this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[0]??.15,this.unprocessedRoutes=[...this.hdRoutes],this.smoothedCursorRoutes=[...this.unprocessedRoutes];const n=[...this.input.obstacles,...this.getJumperPadObstacles()];this.obstacleSHI=new el("flatbush",n),this.boardOutlineRoutes=this.createBoardOutlineRoutes(),this.hdRouteSHI=new al([...this.hdRoutes,...this.boardOutlineRoutes]);for(const[t,e,n]of this.hdRoutes.flatMap(t=>[[t.route[0],t.connectionName,t.rootConnectionName],[t.route[t.route.length-1],t.connectionName,t.rootConnectionName]])){const s=this.obstacleSHI.searchArea(t.x,t.y,.01,.01).filter(e=>e.zLayers?.includes(t.z));if(0===s.length)continue;const o=s[0];this.input.connMap.addConnections([[e,n,...o.offBoardConnectsTo??[],o.obstacleId,...o.connectedTo].filter(Boolean)])}}getSolverName(){return"TraceKeepoutSolver"}originalHdRoutes;hdRoutes;redrawnHdRoutes=[];KEEPOUT_RADIUS_SCHEDULE;currentScheduleIndex=0;currentKeepoutRadius;unprocessedRoutes=[];smoothedCursorRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;lastCursorPosition=null;drawPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;recordedDrawPositions=[];lastCollidingSegments=[];currentTraceJumperSegments=new Map;obstacleSHI;hdRouteSHI;boardOutlineRoutes=[];getSmoothDistance(){return this.currentKeepoutRadius}getJumperPadObstacles(){const t=[];if(!this.input.jumpers)return t;for(const e of this.input.jumpers)for(const n of e.pads)t.push({...n,zLayers:[0]});return t}buildJumperSegmentMap(t){const e=new Map;if(!t.jumpers||0===t.jumpers.length)return e;const n=t.route;for(const s of t.jumpers){let t=-1,o=1/0;for(let e=0;e<n.length-1;e++){const i=n[e],r=n[e+1],a=Math.sqrt((i.x-s.start.x)**2+(i.y-s.start.y)**2),c=Math.sqrt((r.x-s.end.x)**2+(r.y-s.end.y)**2),h=a+c,l=Math.sqrt((i.x-s.end.x)**2+(i.y-s.end.y)**2),d=Math.sqrt((r.x-s.start.x)**2+(r.y-s.start.y)**2),u=l+d,p=Math.min(h,u);(h<=u?a:l)<1&&(h<=u?c:d)<1&&p<o&&(o=p,t=e)}t>=0&&e.set(t,s)}return e}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.currentScheduleIndex++,this.currentScheduleIndex<this.KEEPOUT_RADIUS_SCHEDULE.length?(this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[this.currentScheduleIndex],this.unprocessedRoutes=Vn([...this.processedRoutes],this.currentScheduleIndex),this.smoothedCursorRoutes=[...this.unprocessedRoutes],this.processedRoutes=[],void(this.hdRouteSHI=new al([...this.unprocessedRoutes,...this.boardOutlineRoutes]))):(this.redrawnHdRoutes=this.processedRoutes,void(this.solved=!0));if(this.currentTrace=t,this.currentTrace.route.length<2)return this.processedRoutes.push(this.currentTrace),void(this.currentTrace=null);this.currentTraceJumperSegments=this.buildJumperSegmentMap(this.currentTrace);const e=this.currentTrace.route[0];return this.cursorPosition={...e},this.lastCursorPosition={...e},this.drawPosition={x:e.x,y:e.y},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,void(this.recordedDrawPositions=[{...e}])}this.lastCursorPosition={...this.cursorPosition};const t=this.stepCursorForward();if("end"===t)return void this.finalizeCurrentTrace();if("jumper"===t)return void(this.drawPosition={x:this.cursorPosition.x,y:this.cursorPosition.y});const e=this.getCollidingSegments(this.cursorPosition);this.lastCollidingSegments=e;const n=function(t){const{cursorPosition:e,lastCursorPosition:n,collidingSegments:s,keepoutRadius:o}=t;if(0===s.length)return null;const i=1e-4,r=e.x-n.x,a=e.y-n.y,c=Math.sqrt(r*r+a*a),h=c>i?{x:r/c,y:a/c}:{x:1,y:0},l=-h.y,d=h.x,u=Pd({pos:e,segments:s,dir:h,keepoutRadius:o});if(u>=o)return null;for(let t=1;t<=20;t++){const n=t/20*o,i={x:e.x+l*n,y:e.y+d*n},r=Pd({pos:i,segments:s,dir:h,keepoutRadius:o}),a={x:e.x-l*n,y:e.y-d*n},c=Pd({pos:a,segments:s,dir:h,keepoutRadius:o}),u=r>=o&&Id(e,i,s),p=c>=o&&Id(e,a,s);if(u&&p)return r>=c?i:a;if(u)return i;if(p)return a}const p=o,f=[];for(let t=-60;t<=60;t++){const n=t/60*p,i={x:e.x+l*n,y:e.y+d*n},r=Pd({pos:i,segments:s,dir:h,keepoutRadius:o}),a=Id(e,i,s);f.push({pos:i,clearance:r,dist:Math.abs(n),pathClear:a,index:t})}const m=f.filter(t=>t.pathClear),g=f.findIndex(t=>0===t.index),y=g>=0?g:Math.floor(f.length/2);let x=null;for(let t=y+1;t<f.length-1;t++){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){x=n;break}}let v=null;for(let t=y-1;t>0;t--){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){v=n;break}}let b=null,P=null;if(m.length>0){const t=m.findIndex(t=>0===t.index),e=t>=0?t:Math.floor(m.length/2);for(let t=e+1;t<m.length-1;t++){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){b=n;break}}for(let t=e-1;t>0;t--){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){P=n;break}}}const S=[x,v,b,P,f.find(t=>0===t.index)].filter(t=>null!=t),M=new Set,N=S.filter(t=>{const e=`${t.pos.x.toFixed(6)},${t.pos.y.toFixed(6)}`;return!M.has(e)&&(M.add(e),!0)});if(0===N.length){let t=f[0];if(!t)return null;for(const e of f)e.clearance>t.clearance&&(t=e);return Math.sqrt((t.pos.x-e.x)**2+(t.pos.y-e.y)**2)>i?t.pos:null}let I;if(u<.15*o){I=N[0];for(const t of N)t.clearance>I.clearance&&(I=t)}else{const t=N.filter(t=>t.pathClear),e=t.length>0?t:N;I=e[0];for(const t of e)t.clearance>I.clearance&&(I=t)}return Math.sqrt((I.pos.x-e.x)**2+(I.pos.y-e.y)**2)>i?I.pos:null}({cursorPosition:this.cursorPosition,lastCursorPosition:this.lastCursorPosition,collidingSegments:e,keepoutRadius:this.currentKeepoutRadius});this.drawPosition=n??{...this.cursorPosition};const s=this.recordedDrawPositions[this.recordedDrawPositions.length-1];if(s&&this.drawPosition){const t={x:s.x,y:s.y,z:s.z},e={x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z};this.segmentIntersectsOtherRoutes(t,e)&&(this.drawPosition={...this.cursorPosition})}this.recordedDrawPositions.push({x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z})}getStepDistance(){return this.currentKeepoutRadius/2}getJumperAtCurrentSegmentStart(){return this.currentTraceSegmentT>Dd?null:this.currentTraceJumperSegments.get(this.currentTraceSegmentIndex)??null}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return"end";const t=this.currentTrace.route;let e=this.getStepDistance();for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return"end";const n=this.getJumperAtCurrentSegmentStart();if(n){const e=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1],o=Math.sqrt((e.x-n.start.x)**2+(e.y-n.start.y)**2),i=Math.sqrt((e.x-n.end.x)**2+(e.y-n.end.y)**2),r=o<=i?n.start:n.end,a=o<=i?n.end:n.start;return this.recordedDrawPositions.push({x:r.x,y:r.y,z:e.z,insideJumperPad:!0}),this.recordedDrawPositions.push({x:a.x,y:a.y,z:s.z,insideJumperPad:!0}),this.cursorPosition={x:a.x,y:a.y,z:s.z},this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,"jumper"}const s=t[this.currentTraceSegmentIndex],o=t[this.currentTraceSegmentIndex+1],i=o.x-s.x,r=o.y-s.y,a=Math.sqrt(i*i+r*r);if(0===a){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const c=this.currentTraceSegmentT*a,h=a-c;if(e<=h){const t=c+e;return this.currentTraceSegmentT=t/a,this.cursorPosition={x:s.x+i*this.currentTraceSegmentT,y:s.y+r*this.currentTraceSegmentT,z:s.z},"stepped"}if(e-=h,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},"end"}}return"stepped"}getCollidingSegments(t){if(!this.currentTrace)return[];const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.currentKeepoutRadius,s=[],o=this.obstacleSHI.searchArea(t.x,t.y,n,n).filter(e=>e.zLayers?.includes(t.z));for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.input.connMap.areIdsConnected(e,n.obstacleId))continue;let o=!1;for(const t of n.connectedTo)if(this.input.connMap.areIdsConnected(e,t)){o=!0;break}o||s.push(...Cd(n))}const i=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:o}of i){const i=o.rootConnectionName??o.connectionName;if(i===e)continue;if(this.input.connMap.areIdsConnected(e,i))continue;const r=o.traceThickness??.15;s.push(...Rd(o.route,r,{x:t.x,y:t.y},n,o.jumpers))}return s}positionHasCollision(t,e=0){const n=this.getCollidingSegments(t);for(const s of n)if(X(t,s.start,s.end)<=this.currentKeepoutRadius+e)return!0;return!1}segmentIntersectsOtherRoutes(t,e){if(!this.currentTrace)return!1;const n=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,s=[...this.unprocessedRoutes,...this.smoothedCursorRoutes,...this.processedRoutes];for(const o of s){if((o.rootConnectionName??o.connectionName)!==n)for(let n=0;n<o.route.length-1;n++){const s=o.route[n],i=o.route[n+1];if((s.z===t.z||i.z===t.z)&&((!s.insideJumperPad||!i.insideJumperPad)&&D({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:i.x,y:i.y})))return!0}}return!1}finalizeCurrentTrace(){if(!this.currentTrace)return;const t=this.currentTrace.route[this.currentTrace.route.length-1],e=this.recordedDrawPositions[this.recordedDrawPositions.length-1];e&&e.x===t.x&&e.y===t.y||this.recordedDrawPositions.push({...t});const n=function(t,e){if(t.length<4)return t;let n=[...t],s=!0;for(;s;){s=!1;for(let t=0;t<n.length-1&&!s;t++){const o=n[t],i=n[t+1];if(o.z===i.z)for(let r=t+2;r<n.length-1&&!s;r++){if(r===t+1)continue;const a=n[r],c=n[r+1];if(a.z!==c.z||o.z!==a.z)continue;const h=Ad(o,i,a,c);if(h){if(Ld(n,t+1,r,e))continue;const i=[];for(let e=0;e<=t;e++)i.push(n[e]);i.push({x:h.x,y:h.y,z:o.z});for(let t=r+1;t<n.length;t++)i.push(n[t]);n=i,s=!0}}}}return n}(this.simplifyRoute(this.recordedDrawPositions,this.currentTrace.jumpers),this.currentTrace.jumpers),s={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:this.currentTrace.traceThickness,viaDiameter:this.currentTrace.viaDiameter,route:n,vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(s),this.hdRouteSHI.removeRoute(this.currentTrace.connectionName),this.hdRouteSHI.addRoute(s),this.currentTrace=null,this.cursorPosition=null,this.lastCursorPosition=null,this.drawPosition=null,this.recordedDrawPositions=[]}isJumperEndpoint(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Dd&&Math.abs(t.y-n.start.y)<Dd||Math.abs(t.x-n.end.x)<Dd&&Math.abs(t.y-n.end.y)<Dd)return!0;return!1}simplifyRoute(t,e){if(t.length<=2)return t;const n=[t[0]];for(let s=1;s<t.length-1;s++){const o=n[n.length-1],i=t[s],r=t[s+1];if(this.isJumperEndpoint(i,e)){n.push(i);continue}if(i.z!==o.z||i.z!==r.z){n.push(i);continue}const a=i.x-o.x,c=i.y-o.y,h=r.x-i.x,l=a*(r.y-i.y)-c*h,d=1e-6;Math.abs(l)>d&&n.push(i)}return n.push(t[t.length-1]),n}createBoardOutlineRoutes(){const t=[];if(!this.input.srj)return t;const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];const o=this.input.srj.layerCount??2;for(let e=0;e<s.length;e++){const n=s[e],i=s[(e+1)%s.length];for(let s=0;s<o;s++)t.push({connectionName:`__board_outline___${e}_z${s}`,traceThickness:.01,viaDiameter:0,route:[{x:n.x,y:n.y,z:s},{x:i.x,y:i.y,z:s}],vias:[]})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:`Trace Keepout Solver (radius: ${this.currentKeepoutRadius.toFixed(2)})`};for(const e of this.originalHdRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"rgba(0,0,0,0.25)",strokeWidth:1.5*(e.traceThickness??.15)})}if(this.input.jumpers)for(const e of this.input.jumpers){for(const n of e.pads){const e=n.connectedTo.length>0?n.connectedTo.join(", "):"unused",s=n.connectedTo.length>0?this.input.colorMap[n.connectedTo[0]]||"#888888":"rgba(128, 128, 128, 0.5)";t.rects.push({center:n.center,width:n.width,height:n.height,fill:s,stroke:"rgba(0, 0, 0, 0.5)",label:`Jumper pad (${e})`})}e.pads.length>=2&&t.lines.push({points:[e.pads[0].center,e.pads[1].center],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.2,label:"Jumper body"})}for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}if(this.input.srj){const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];for(let e=0;e<s.length;e++){const n=s[e],o=s[(e+1)%s.length];t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"rgba(0, 128, 0, 0.6)",strokeWidth:.1,label:"Board outline"})}}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888",s=new Set;if(e.jumpers&&e.jumpers.length>0)for(const t of e.jumpers)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1],r=Math.abs(o.x-t.start.x)<Dd&&Math.abs(o.y-t.start.y)<Dd&&Math.abs(i.x-t.end.x)<Dd&&Math.abs(i.y-t.end.y)<Dd,a=Math.abs(o.x-t.end.x)<Dd&&Math.abs(o.y-t.end.y)<Dd&&Math.abs(i.x-t.start.x)<Dd&&Math.abs(i.y-t.start.y)<Dd;if(r||a){s.add(n);break}}for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];s.has(n)?t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:"rgba(128, 128, 128, 0.6)",strokeDash:"2 2",label:`${e.connectionName} (jumper segment - fixed)`}):o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Vh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}if(this.currentTrace&&this.recordedDrawPositions.length>0){this.input.colorMap[this.currentTrace.connectionName];for(let e=0;e<this.recordedDrawPositions.length-1;e++){const n=this.recordedDrawPositions[e],s=this.recordedDrawPositions[e+1];t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"green",strokeWidth:this.currentTrace.traceThickness})}if(this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentKeepoutRadius,stroke:"orange",fill:"none"}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}),this.lastCursorPosition)){const e=this.cursorPosition.x-this.lastCursorPosition.x,n=this.cursorPosition.y-this.lastCursorPosition.y,s=Math.sqrt(e*e+n*n),o=s>1e-4?{x:e/s,y:n/s}:{x:1,y:0},i=this.currentKeepoutRadius/4,r={x:this.cursorPosition.x-o.x*i,y:this.cursorPosition.y-o.y*i},a={x:this.cursorPosition.x+o.x*i,y:this.cursorPosition.y+o.y*i};t.lines.push({points:[r,a],strokeColor:"cyan",strokeWidth:.05,label:"Projected segment"})}this.drawPosition&&t.points.push({x:this.drawPosition.x,y:this.drawPosition.y,color:"lime",label:"Draw"});for(const e of this.lastCollidingSegments)t.lines.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:"rgba(255, 0, 255, 0.8)",strokeWidth:.02,label:"Colliding segment"})}if(!this.solved)for(const e of this.smoothedCursorRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"gray"})}return t}getRedrawnHdRoutes(){return this.redrawnHdRoutes}},Yd=class extends Ln{constructor(t){super(),this.input=t,this.unprocessedObstacles=hl(this.input.srj.obstacles,this.input.srj.layerCount).filter(t=>t.offBoardConnectsTo&&t.offBoardConnectsTo.length>0),this.unprocessedObstacles.forEach((t,e)=>{t.obstacleId=t.obstacleId??`__obs${e}`}),this.offBoardConnMap=new Hh({}),this.offBoardConnMap.addConnections(this.unprocessedObstacles.filter(t=>t.offBoardConnectsTo?.length).map(t=>[t.obstacleId,...t.offBoardConnectsTo??[]])),this.nodeTree=new kn(this.input.capacityMeshNodes)}getSolverName(){return"RelateNodesToOffBoardConnectionsSolver"}unprocessedObstacles;nodeTree;offBoardConnMap;nodesInNet=new Map;lastProcessedObstacle;_step(){const t=this.unprocessedObstacles.pop();if(this.lastProcessedObstacle=t,!t)return void(this.solved=!0);const e=this.offBoardConnMap.getNetConnectedToId(t.obstacleId),n=this.nodeTree.getNodesInArea(t.center.x,t.center.y,.01,.01).filter(e=>e.availableZ.some(e=>t.zLayers?.includes(e))).filter(e=>Math.abs(e.center.x-t.center.x)<.01&&Math.abs(e.center.y-t.center.y)<.01),s=n.map(t=>t.capacityMeshNodeId),o=this.nodesInNet.get(e)??[],i=[...o.map(t=>t.capacityMeshNodeId),...s];for(const t of o)t._offBoardConnectedCapacityMeshNodeIds=i;for(const t of n)t._offBoardConnectedCapacityMeshNodeIds=i,t._offBoardConnectionId=e;this.nodesInNet.set(e,[...o,...n])}getOutput(){return{capacityNodes:this.input.capacityMeshNodes}}visualize(){const t={rects:[],lines:[],points:[],circles:[]},e=new Set;for(const[t,n]of this.nodesInNet)for(const t of n)e.add(t.capacityMeshNodeId);for(const n of this.input.capacityMeshNodes)e.has(n.capacityMeshNodeId)||t.rects.push({center:n.center,width:n.width-.1,height:n.height-.1,fill:"rgba(0, 0, 0, 0.2)"});this.lastProcessedObstacle&&t.rects.push({center:this.lastProcessedObstacle.center,width:this.lastProcessedObstacle.width,height:this.lastProcessedObstacle.height,fill:"rgba(255, 0, 0, 0.5)"});for(const[e,n]of this.nodesInNet.entries()){for(const s of n)t.rects.push({center:s.center,width:s.width,height:s.height,fill:In(e,.2),label:`OffBoardConn: ${e}`});for(const s of n)for(const o of n)s.capacityMeshNodeId!==o.capacityMeshNodeId&&t.lines.push({points:[s.center,o.center],strokeColor:In(e,1)})}return t}},Xd=.1,kd=.1;function $d(t,e,n,s,o,i){return(o-t)*(s-e)-(i-e)*(n-t)}function Bd(t,e,n,s,o,i){return Math.min(t,n)<=o&&o<=Math.max(t,n)&&Math.min(e,s)<=i&&i<=Math.max(e,s)}function jd(t,e,n,s,o,i,r,a){const c=$d(o,i,r,a,t,e),h=$d(o,i,r,a,n,s),l=$d(t,e,n,s,o,i),d=$d(t,e,n,s,r,a);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)||(!(0!==c||!Bd(o,i,r,a,t,e))||(!(0!==h||!Bd(o,i,r,a,n,s))||(!(0!==l||!Bd(t,e,n,s,o,i))||!(0!==d||!Bd(t,e,n,s,r,a)))))}function Wd(t,e,n,s,o,i){const r=o-n,a=i-s,c=t-n,h=e-s,l=r*r+a*a;if(0===l){return{x:n,y:s,distSq:c*c+h*h}}let d=(c*r+h*a)/l;d=Math.max(0,Math.min(1,d));const u=n+d*r,p=s+d*a,f=t-u,m=e-p;return{x:u,y:p,distSq:f*f+m*m}}var Hd=class extends Ln{getSolverName(){return"SimpleHighDensitySolver"}unsolvedNodes;allNodes;routes;colorMap;traceWidth;viaDiameter;numMovablePoints;currentNode=null;lastNode=null;currentNodeStep=0;routesInProgress=[];pushMargin;currentNodeBounds=null;constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.1,viaDiameter:s=.3,pushMargin:o=.3,numMovablePoints:i=2}){if(super(),i<1||i>3)throw new Error(`numMovablePoints must be 1, 2, or 3, got ${i}`);this.allNodes=[...t],this.unsolvedNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.viaDiameter=s,this.numMovablePoints=i,this.pushMargin=o,this.MAX_ITERATIONS=10*t.length+1}_step(){if(null===this.currentNode){if(0===this.unsolvedNodes.length)return void(this.solved=!0);this.lastNode=this.currentNode,this.currentNode=this.unsolvedNodes.pop(),this.currentNodeStep=0,this.routesInProgress=[],this._initializeRoutesForCurrentNode()}this.currentNodeStep>0&&this._runForceDirectedStep(),this.currentNodeStep++,this.currentNodeStep>=10&&(this._finalizeRoutesForCurrentNode(),this.lastNode=this.currentNode,this.currentNode=null)}_initializeRoutesForCurrentNode(){const t=this.currentNode,e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2;this.currentNodeBounds={minX:e,maxX:n,minY:s,maxY:o};const i=new Map;for(const e of t.portPoints)i.has(e.connectionName)||i.set(e.connectionName,[]),i.get(e.connectionName).push({x:e.x,y:e.y,z:e.z,rootConnectionName:e.rootConnectionName});for(const[t,e]of i){if(e.length<2)continue;const n=e[0],s=e[e.length-1],o=n.z,i=s.x-n.x,r=s.y-n.y,a=Math.sqrt(i*i+r*r),c=a>0?i/a:0,h=a>0?r/a:0,l=[];this.numMovablePoints>=1&&l.push({x:n.x+c*kd,y:n.y+h*kd,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=2&&l.push({x:s.x-c*kd,y:s.y-h*kd,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=3&&l.push({x:n.x+i/2,y:n.y+r/2,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.routesInProgress.push({connectionName:t,rootConnectionName:n.rootConnectionName,startPoint:{x:n.x,y:n.y,z:o},endPoint:{x:s.x,y:s.y,z:o},movablePoints:l})}}_runForceDirectedStep(){const t=this.currentNodeBounds,e=[];for(const t of this.routesInProgress)e.push(...t.movablePoints);const n=new Map;for(const t of e)n.set(t,{fx:0,fy:0});const s=.3+this.pushMargin,o=new Map;for(const t of this.routesInProgress){const e=[{x:t.startPoint.x,y:t.startPoint.y,movablePoint:null}];1===t.movablePoints.length?e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}):2===t.movablePoints.length?(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})):3===t.movablePoints.length&&(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[2].x,y:t.movablePoints[2].y,movablePoint:t.movablePoints[2]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})),e.push({x:t.endPoint.x,y:t.endPoint.y,movablePoint:null}),o.set(t,e)}for(const i of e){const e=n.get(i),r=i.x-t.minX,a=t.maxX-i.x,c=t.maxY-i.y,h=i.y-t.minY;r<s&&(e.fx+=Xd*(s-r)),a<s&&(e.fx-=Xd*(s-a)),h<s&&(e.fy+=Xd*(s-h)),c<s&&(e.fy-=Xd*(s-c));for(const t of this.routesInProgress){if(t.rootConnectionName===i.rootConnectionName)continue;const r=o.get(t);for(let t=0;t<r.length-1;t++){const o=r[t],a=r[t+1],c=Wd(i.x,i.y,o.x,o.y,a.x,a.y),h=Math.sqrt(c.distSq);if(h>0&&h<2*s){const t=i.x-c.x,s=i.y-c.y,r=.002/c.distSq,h=r*t,l=r*s;e.fx+=h,e.fy+=l;const d=o.movablePoint,u=a.movablePoint;if(d&&u){const t=n.get(d),e=n.get(u);t.fx-=h/2,t.fy-=l/2,e.fx-=h/2,e.fy-=l/2}else if(d){const t=n.get(d);t.fx-=h,t.fy-=l}else if(u){const t=n.get(u);t.fx-=h,t.fy-=l}}}}}const i=t=>t.movablePoint?{x:t.movablePoint.x,y:t.movablePoint.y}:{x:t.x,y:t.y},r=t=>{let e=null;for(const n of this.routesInProgress)if(n.movablePoints.includes(t)){e=n;break}if(!e)return!1;const n=o.get(e);let s=-1;for(let e=0;e<n.length;e++)if(n[e].movablePoint===t){s=e;break}if(-1===s)return!1;const r=[];if(s>0){const e=i(n[s-1]);r.push({ax:e.x,ay:e.y,bx:t.x,by:t.y})}if(s<n.length-1){const e=i(n[s+1]);r.push({ax:t.x,ay:t.y,bx:e.x,by:e.y})}for(const t of this.routesInProgress){if(t.rootConnectionName===e.rootConnectionName)continue;const n=o.get(t);for(let t=0;t<n.length-1;t++){const e=i(n[t]),s=i(n[t+1]);for(const t of r)if(jd(t.ax,t.ay,t.bx,t.by,e.x,e.y,s.x,s.y))return!0}}return!1};for(const s of e){const e=n.get(s);s.forceX=e.fx,s.forceY=e.fy;const o=s.x,i=s.y;s.x+=e.fx,s.y+=e.fy,s.x=Math.max(t.minX,Math.min(t.maxX,s.x)),s.y=Math.max(t.minY,Math.min(t.maxY,s.y)),r(s)&&(s.x=o,s.y=i)}}_finalizeRoutesForCurrentNode(){for(const t of this.routesInProgress){const{connectionName:e,rootConnectionName:n,startPoint:s,endPoint:o,movablePoints:i}=t,r=[{x:s.x,y:s.y,z:s.z}];1===i.length?r.push({x:i[0].x,y:i[0].y,z:i[0].z}):2===i.length?(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})):3===i.length&&(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[2].x,y:i[2].y,z:i[2].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})),r.push({x:o.x,y:o.y,z:o.z});const a={connectionName:e,rootConnectionName:n,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:r,vias:[]};this.routes.push(a)}this.routesInProgress=[]}_getNodeBounds(t){return{minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.unsolvedNodes){if(e===this.currentNode)continue;const n=this._getNodeBounds(e);t.rects.push({center:{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2},width:n.maxX-n.minX,height:n.maxY-n.minY,fill:"rgba(0, 0, 0, 0.08)",stroke:"rgba(0, 0, 0, 0.2)",label:e.capacityMeshNodeId})}if(this.lastNode){const e=this._getNodeBounds(this.lastNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 0, 255, 0.6)"})}if(this.currentNode){const e=this._getNodeBounds(this.currentNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 200, 0, 0.6)"})}for(const e of this.unsolvedNodes){const n=new Map;for(const t of e.portPoints)n.has(t.connectionName)||n.set(t.connectionName,[]),n.get(t.connectionName).push({x:t.x,y:t.y});for(const[e,s]of n)s.length<2||t.lines.push({points:s.map(t=>({x:t.x,y:t.y})),label:e,strokeColor:"gray",strokeWidth:this.traceWidth})}for(const e of this.routes){const n=jn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:Nn(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});const s=e.route;for(let e=0;e<s.length;e++){const n=s[e],o=0===e,i=e===s.length-1,r=!o&&!i;let a;a=o?"start":i?"end":`M${e}`,t.points.push({x:n.x,y:n.y,label:a,color:r?"orange":"blue"})}}for(const e of this.routesInProgress){const{startPoint:n,endPoint:s,movablePoints:o,connectionName:i}=e,r=this.colorMap[i]??"gray",a=[{x:n.x,y:n.y}];1===o.length?a.push({x:o[0].x,y:o[0].y}):2===o.length?(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[1].x,y:o[1].y})):3===o.length&&(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[2].x,y:o[2].y}),a.push({x:o[1].x,y:o[1].y})),a.push({x:s.x,y:s.y}),t.lines.push({points:a,label:i,strokeColor:r,strokeWidth:this.traceWidth}),t.points.push({x:n.x,y:n.y,label:"start",color:"blue"});for(let e=0;e<o.length;e++){const n=o[e];if(t.points.push({x:n.x,y:n.y,label:`M${e+1}`,color:"orange"}),void 0!==n.forceX&&void 0!==n.forceY){if(Math.sqrt(n.forceX*n.forceX+n.forceY*n.forceY)>.001){const s=5;t.lines.push({points:[{x:n.x,y:n.y},{x:n.x+n.forceX*s,y:n.y+n.forceY*s}],strokeColor:"red",strokeWidth:.02,label:`F${e+1}`});const o=.05,i=n.x+n.forceX*s,r=n.y+n.forceY*s,a=Math.atan2(n.forceY,n.forceX);t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a-Math.PI/6),y:r-o*Math.sin(a-Math.PI/6)}],strokeColor:"red",strokeWidth:.02}),t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a+Math.PI/6),y:r-o*Math.sin(a+Math.PI/6)}],strokeColor:"purple",strokeWidth:.02})}}}t.points.push({x:s.x,y:s.y,label:"end",color:"blue"})}return t}},Ud=({connMap:t,connectionsWithResults:e,inputNodes:n,obstacles:s})=>{const o=s.filter(t=>t.offBoardConnectsTo?.length);if(0===o.length)return;const i=new On({});i.addConnections(o.map((t,e)=>[t.obstacleId??`__obs${e}`,...t.offBoardConnectsTo??[]]));const r=new Map(n.map(t=>[t.capacityMeshNodeId,t]));for(const n of e){if(!n.path)continue;const e=n.connection.rootConnectionName??n.connection.name,s=new Set;for(const t of n.path){const e=r.get(t.currentNodeId);if(e?._offBoardConnectionId&&s.add(e._offBoardConnectionId),t.throughNodeId){const e=r.get(t.throughNodeId);e?._offBoardConnectionId&&s.add(e._offBoardConnectionId)}}for(const n of s){const s=i.getIdsConnectedToNet(n);s?.length&&t.addConnections([[e,...s]])}}};function Vd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Gd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline2"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceKeepoutSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Vd("netToPointPairsSolver",jh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Vd("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Vd("relateNodesToOffBoardConnections",Yd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),Vd("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Vd("availableSegmentPointSolver",Fn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Vd("portPointPathingSolver",Ah,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:100*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!1,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Ud({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),Vd("multiSectionPortPointOptimizer",Dh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints}]}),Vd("highDensitySolver",Hd,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,connMap:t.connMap}]),Vd("highDensityStitchSolver",Kh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Vd("traceSimplificationSolver",Il,t=>[{hdRoutes:t.highDensityStitchSolver?.mergedHdRoutes??t.highDensitySolver?.routes??t.highDensityRouteSolver?.routes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Vd("traceKeepoutSolver",Fd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??[],obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}]),Vd("traceWidthSolver",_l,t=>[{hdRoutes:t.traceKeepoutSolver?.redrawnHdRoutes??[],connection:t.srj.connections,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.offboardPathFragmentSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensitySolver?.visualize(),p=this.simpleHighDensityRouteSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),m=this.traceSimplificationSolver?.visualize(),g=this.traceKeepoutSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,r,a,c,h,l,d?Bn(b,d):null,u?Bn(b,u):null,p?Bn(b,p):null,f,m,g,y,this.solved?Bn(b,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`,i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Zd=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver2"}unsolvedRoutes;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Map;for(const e of t.connectionPathResults)n.set(e.connection.name,e);const s=new Map;for(const e of t.hdRoutes){const t=s.get(e.connectionName);t?t.push(e):s.set(e.connectionName,[e])}this.unsolvedRoutes=[];for(const[e,o]of s.entries()){const s=t.connections.find(t=>t.name===e);if(!s)continue;const i=n.get(e);let r=[];i?.path&&(r=i.path.map(t=>t.currentNodeId));const a={...s.pointsToConnect[0],z:wn(Cn(s.pointsToConnect[0]),t.layerCount)},c={...s.pointsToConnect[1],z:wn(Cn(s.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:e,hdRoutes:o,nodeOrder:r,start:a,end:c})}this.MAX_ITERATIONS=1e5}_step(){const t=this.unsolvedRoutes.pop();if(!t)return void(this.solved=!0);const e=this.stitchOrderedRoutes(t);this.mergedHdRoutes.push(e)}stitchOrderedRoutes(t){const{connectionName:e,hdRoutes:n,nodeOrder:s,start:o,end:i}=t;if(0===n.length)return{connectionName:e,traceThickness:this.defaultTraceThickness,viaDiameter:this.defaultViaDiameter,route:[o,i],vias:[],jumpers:[]};let r;r=s.length>0?this.orderRoutesByNodePath(n,s,o,e):this.orderRoutesByProximity(n,o);const a=[],c=[],h=[];a.push({x:o.x,y:o.y,z:o.z});for(let t=0;t<r.length;t++){const e=r[t],n=a[a.length-1],s=e.route[0],o=e.route[e.route.length-1],i=k(n,s),l=k(n,o),d=Math.min(i,l);if(t>0&&d>1)continue;let u;u=i<=l?[...e.route]:[...e.route].reverse();const p=.001;u.length>0&&k(n,u[0])<p&&(u=u.slice(1)),a.push(...u),c.push(...e.vias),e.jumpers&&h.push(...e.jumpers)}const l=k(a[a.length-1],i);return l>.001&&l<5&&a.push({x:i.x,y:i.y,z:i.z}),{connectionName:e,rootConnectionName:n[0]?.rootConnectionName,traceThickness:n[0]?.traceThickness??this.defaultTraceThickness,viaDiameter:n[0]?.viaDiameter??this.defaultViaDiameter,route:a,vias:c,jumpers:h}}orderRoutesByNodePath(t,e,n,s){if(0===t.length)return[];const o=new Set(t);let i=null,r=1/0;for(const t of o){const e=t.route[0],s=t.route[t.route.length-1],o=Math.min(k(n,e),k(n,s));o<r&&(r=o,i=t)}if(!i)return[];o.delete(i);const a=i.route[0],c=i.route[i.route.length-1];let h,l;k(n,a)<=k(n,c)?(h=a,l=c):(h=c,l=a);const d=(t,e)=>{let n=0;for(const s of o){if(s===e)continue;const o=s.route[0],i=s.route[s.route.length-1];(k(t,o)<10||k(t,i)<10)&&n++}return n},u=[i];let p=l;for(;o.size>0;){let t=null,e=1/0,n=-1;for(const s of o){const o=s.route[0],i=s.route[s.route.length-1],r=k(p,o),a=k(p,i),c=Math.min(r,a);if(c>=10)continue;const h=d(r<=a?i:o,s),l=0===h,u=0===n,f=c-e;let m=!1;m=null===t||(!!(!l&&u&&f<5)||!(l&&!u&&f>-5)&&c<e),m&&(e=c,t=s,n=h)}if(!t)break;{u.push(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const f=[];for(p=h;o.size>0;){let t=null,e=1/0,s=-1;const i=k(p,n);for(const r of o){const o=r.route[0],a=r.route[r.route.length-1],c=k(p,o),h=k(p,a),l=Math.min(c,h);if(l>=10)continue;const u=c<=h?a:o;if(k(u,n)>i+2)continue;const f=d(u,r),m=0===f,g=0===s,y=l-e;let x=!1;x=null===t||(!!(!m&&g&&y<5)||!(m&&!g&&y>-5)&&l<e),x&&(e=l,t=r,s=f)}if(!t)break;{f.unshift(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const m=[...f,...u];if(o.size>0){const e=[...o].map(t=>{const e=t.route[0],n=t.route[t.route.length-1];return`start=(${e.x.toFixed(2)},${e.y.toFixed(2)}) end=(${n.x.toFixed(2)},${n.y.toFixed(2)})`});console.warn(`[StitchSolver] Skipped ${o.size} routes for connection ${t[0]?.connectionName??"?"}, skipped routes: ${e.join("; ")}`)}return m}orderRoutesByProximity(t,e){const n=new Set(t),s=[];let o=e;for(;n.size>0;){let t=null,e=1/0,i=!1;for(const s of n){const n=s.route[0],r=s.route[s.route.length-1],a=k(o,n),c=k(o,r);a<e&&(e=a,t=s,i=!1),c<e&&(e=c,t=s,i=!0)}if(!t)break;{s.push(t),n.delete(t);const e=t.route[0],r=t.route[t.route.length-1];o=i?e:r}}return s}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 2"};for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?Nn(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?Nn(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Vh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End`});for(let s=0;s<e.hdRoutes.length;s++){const o=e.hdRoutes[s];if(o.route.length>1&&t.lines?.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:Nn(n,.5),strokeDash:"10 5",label:`segment ${s}`}),o.jumpers&&o.jumpers.length>0){const e=Vh(o.jumpers,{color:n,label:o.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},qd=Object.create,Jd=Object.defineProperty,Kd=Object.getOwnPropertyDescriptor,Qd=Object.getOwnPropertyNames,tu=Object.getPrototypeOf,eu=Object.prototype.hasOwnProperty,nu=(t,e)=>function(){return e||(0,t[Qd(t)[0]])((e={exports:{}}).exports,e),e.exports},su=(t,e,n)=>(n=null!=t?qd(tu(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Qd(e))eu.call(t,o)||o===n||Jd(t,o,{get:()=>e[o],enumerable:!(s=Kd(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Jd(n,"default",{value:t,enumerable:!0}),t)),ou=nu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),iu=nu({"node_modules/kind-of/index.js"(t,e){var n=ou(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),ru=nu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),au=nu({"node_modules/deep-rename-keys/index.js"(t,e){var n=iu(),s=ru();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),cu=nu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),hu=nu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=cu(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),lu=nu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=cu(),s=hu(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:du,sin:uu,PI:pu}=Math,{tan:fu}=Math,mu=(su(au()),su(lu()),class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.constructor.name} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.constructor.name} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}}),gu=t=>t?`hsl(${(t=>{let e=0;for(let n=0;n<t.length;n++)e=779*t.charCodeAt(n)+((e<<5)-e);return e})(t)%360}, 100%, 50%)`:"rgba(0, 0, 0, 0.5)",yu=t=>[[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY}],[{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY}],[{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],[{x:t.minX,y:t.maxY},{x:t.minX,y:t.minY}]];function xu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=s-n,a=i-o,c=1e-6;return Math.abs(t.y-i)<c?t.x-n:Math.abs(t.x-s)<c?r+(i-t.y):Math.abs(t.y-o)<c?r+a+(s-t.x):Math.abs(t.x-n)<c?2*r+a+(t.y-o):0}function vu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=1e-6,a=Math.abs(t.y-i)<r,c=Math.abs(t.y-o)<r,h=Math.abs(t.x-s)<r,l=Math.abs(t.x-n)<r;if(a&&h)return{x:-Math.SQRT1_2,y:-Math.SQRT1_2};if(a&&l)return{x:Math.SQRT1_2,y:-Math.SQRT1_2};if(c&&h)return{x:-Math.SQRT1_2,y:Math.SQRT1_2};if(c&&l)return{x:Math.SQRT1_2,y:Math.SQRT1_2};if(a)return{x:0,y:-1};if(c)return{x:0,y:1};if(h)return{x:-1,y:0};if(l)return{x:1,y:0};const d=(o+i)/2,u=(n+s)/2-t.x,p=d-t.y,f=Math.hypot(u,p);return f>0?{x:u/f,y:p/f}:{x:0,y:-1}}function bu(t,e,n,s,o,i,r,a,c,h){for(let l=0;l<=h;l++){const d=l/h,u=1-d,p=u*u,f=p*u,m=d*d,g=m*d,y=2*l;c[y]=f*t+3*p*d*n+3*u*m*o+g*r,c[y+1]=f*e+3*p*d*s+3*u*m*i+g*a}}function Pu(t,e,n,s,o){const i=[];for(let r=0;r<=o;r++){const a=r/o,c=1-a,h=c*c,l=h*c,d=a*a,u=d*a;i.push({x:l*t.x+3*h*a*e.x+3*c*d*n.x+u*s.x,y:l*t.y+3*h*a*e.y+3*c*d*n.y+u*s.y})}return i}function Su(t,e,n,s,o,i){const r=o-n,a=i-s,c=r*r+a*a;if(0===c){const o=t-n,i=e-s;return o*o+i*i}const h=Math.max(0,Math.min(1,((t-n)*r+(e-s)*a)/c)),l=t-(n+h*r),d=e-(s+h*a);return l*l+d*d}function Mu(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)?0:Math.min(Su(t,e,o,i,r,a),Su(n,s,o,i,r,a),Su(o,i,t,e,n,s),Su(r,a,t,e,n,s))}function Nu(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)}function Iu(t,e,n,s,o){const i=t=>(t%o+o)%o,r=i(t),a=i(e),c=i(n),h=i(s),[l,d]=r<a?[r,a]:[a,r];return c>l&&c<d&&h>l&&h<d}function _u(t,e){let n=1/0,s=-1/0,o=1/0,i=-1/0;for(let r=0;r<e;r++){const e=t[2*r],a=t[2*r+1];e<n&&(n=e),e>s&&(s=e),a<o&&(o=a),a>i&&(i=a)}return{minX:n,maxX:s,minY:o,maxY:i}}var Cu=class extends mu{constructor(t){super(),this.problem=t;for(const t of this.problem.obstacles)t.outerSegments=yu(t);this.precomputeObstacles()}outputTraces=[];traces=[];optimizationStep=0;maxOptimizationSteps=100;sampledPoints=[];traceBounds=[];obstacleSegments=new Float64Array(0);obstacleNetworkIds=[];numObstacleSegments=0;collisionPairs=[];lastCost=1/0;stagnantSteps=0;effectiveTraceToTraceSpacing=0;getConstructorParams(){return this.problem}precomputeObstacles(){const{obstacles:t}=this.problem;let e=0;for(const n of t)n.outerSegments&&(e+=n.outerSegments.length);this.obstacleSegments=new Float64Array(4*e),this.obstacleNetworkIds=[],this.numObstacleSegments=e;let n=0;for(const e of t)if(e.outerSegments)for(const t of e.outerSegments)this.obstacleSegments[n++]=t[0].x,this.obstacleSegments[n++]=t[0].y,this.obstacleSegments[n++]=t[1].x,this.obstacleSegments[n++]=t[1].y,this.obstacleNetworkIds.push(e.networkId)}initializeTraces(){const{bounds:t,waypointPairs:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=s-n,a=i-o,c=2*r+2*a,h=function(t){return{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}}(t),l=e.map((e,n)=>({pair:e,t1:xu(e.start,t),t2:xu(e.end,t),idx:n})),d=l.map(()=>[]),u=l.map(()=>[]);for(const t of l)for(const e of l)if(t.idx!==e.idx){if(t.pair.networkId&&e.pair.networkId&&t.pair.networkId===e.pair.networkId)continue;Iu(e.t1,e.t2,t.t1,t.t2,c)&&(d[t.idx].push(e.idx),u[e.idx].push(t.idx))}const p=d.map(t=>t.length),f=Math.max(...p,1);this.traces=l.map(({pair:e,t1:n,t2:s,idx:o})=>{const i=vu(e.start,t),c=vu(e.end,t),l=Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),m=p[o]/f,g=(e.start.x+e.end.x)/2,y=(e.start.y+e.end.y)/2,x=l*(.25+.15*(1-Math.hypot(g-h.x,y-h.y)/Math.hypot(r/2,a/2)))*(1-.3*m),v=.05*Math.min(r,a),b=Math.max(v,x),P=Math.max(v,x);return{waypointPair:e,ctrl1:{x:e.start.x+b*i.x,y:e.start.y+b*i.y},ctrl2:{x:e.end.x+P*c.x,y:e.end.y+P*c.y},networkId:e.networkId,t1:n,t2:s,perpDir1:i,perpDir2:c,d1:b,d2:P,containedBy:d[o],contains:u[o]}}),this.sampledPoints=this.traces.map(()=>new Float64Array(12)),this.traceBounds=this.traces.map(()=>({minX:0,maxX:0,minY:0,maxY:0})),this.updateSampledTraces(),this.updateCollisionPairs()}updateSampledTraces(){for(let t=0;t<this.traces.length;t++){const e=this.traces[t];bu(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=_u(this.sampledPoints[t],6)}}updateSingleTraceSample(t){const e=this.traces[t];bu(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=_u(this.sampledPoints[t],6)}updateControlPointsFromDistances(t){const e=this.traces[t],{minX:n,maxX:s,minY:o,maxY:i}=this.problem.bounds,r=1e-6;let a=e.waypointPair.start.x+e.d1*e.perpDir1.x,c=e.waypointPair.start.y+e.d1*e.perpDir1.y,h=e.waypointPair.end.x+e.d2*e.perpDir2.x,l=e.waypointPair.end.y+e.d2*e.perpDir2.y;const d=e.waypointPair.start;Math.abs(d.x-n)<r&&(a=Math.max(a,n)),Math.abs(d.x-s)<r&&(a=Math.min(a,s)),Math.abs(d.y-o)<r&&(c=Math.max(c,o)),Math.abs(d.y-i)<r&&(c=Math.min(c,i));const u=e.waypointPair.end;Math.abs(u.x-n)<r&&(h=Math.max(h,n)),Math.abs(u.x-s)<r&&(h=Math.min(h,s)),Math.abs(u.y-o)<r&&(l=Math.max(l,o)),Math.abs(u.y-i)<r&&(l=Math.min(l,i)),a=Math.max(n,Math.min(s,a)),c=Math.max(o,Math.min(i,c)),h=Math.max(n,Math.min(s,h)),l=Math.max(o,Math.min(i,l)),e.ctrl1.x=a,e.ctrl1.y=c,e.ctrl2.x=h,e.ctrl2.y=l}updateCollisionPairs(){const t=this.effectiveTraceToTraceSpacing;this.collisionPairs=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX+t>=r.minX&&r.maxX+t>=i.minX&&i.maxY+t>=r.minY&&r.maxY+t>=i.minY&&this.collisionPairs.push([e,n])}}computeTotalCost(){const{preferredObstacleToTraceSpacing:t}=this.problem,e=this.effectiveTraceToTraceSpacing,n=e**2,s=t**2;let o=0;for(const[t,s]of this.collisionPairs){const i=this.sampledPoints[t],r=this.sampledPoints[s];for(let t=0;t<5;t++){const s=i[2*t],a=i[2*t+1],c=i[2*(t+1)],h=i[2*(t+1)+1];for(let t=0;t<5;t++){const i=Mu(s,a,c,h,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]);if(i<n){o+=(e-Math.sqrt(i))**2,i<1e-18&&(o+=20*n)}}}}for(let e=0;e<this.traces.length;e++){const n=this.traces[e],i=this.sampledPoints[e],r=this.traceBounds[e];for(let e=0;e<this.numObstacleSegments;e++){if(n.networkId&&this.obstacleNetworkIds[e]&&n.networkId===this.obstacleNetworkIds[e])continue;const a=4*e,c=this.obstacleSegments[a],h=this.obstacleSegments[a+1],l=this.obstacleSegments[a+2],d=this.obstacleSegments[a+3],u=Math.min(c,l),p=Math.max(c,l),f=Math.min(h,d),m=Math.max(h,d);if(!(r.maxX+t<u||p+t<r.minX||r.maxY+t<f||m+t<r.minY))for(let e=0;e<5;e++){const n=Mu(i[2*e],i[2*e+1],i[2*(e+1)],i[2*(e+1)+1],c,h,l,d);if(n<s){o+=(t-Math.sqrt(n))**2,n<1e-18&&(o+=20*s)}}}}return o}computeCostForTrace(t){const{preferredObstacleToTraceSpacing:e}=this.problem,n=this.effectiveTraceToTraceSpacing,s=n**2,o=e**2,i=this.traces[t],r=this.sampledPoints[t],a=this.traceBounds[t];let c=0;for(let e=0;e<this.traces.length;e++){if(e===t)continue;const o=this.traces[e];if(i.networkId&&o.networkId&&i.networkId===o.networkId)continue;const h=this.traceBounds[e];if(a.maxX+n<h.minX||h.maxX+n<a.minX||a.maxY+n<h.minY||h.maxY+n<a.minY)continue;const l=this.sampledPoints[e];for(let t=0;t<5;t++){const e=r[2*t],o=r[2*t+1],i=r[2*(t+1)],a=r[2*(t+1)+1];for(let t=0;t<5;t++){const r=Mu(e,o,i,a,l[2*t],l[2*t+1],l[2*(t+1)],l[2*(t+1)+1]);if(r<s){c+=(n-Math.sqrt(r))**2,r<1e-18&&(c+=20*s)}}}}for(let t=0;t<this.numObstacleSegments;t++){if(i.networkId&&this.obstacleNetworkIds[t]&&i.networkId===this.obstacleNetworkIds[t])continue;const n=4*t,s=this.obstacleSegments[n],h=this.obstacleSegments[n+1],l=this.obstacleSegments[n+2],d=this.obstacleSegments[n+3],u=Math.min(s,l),p=Math.max(s,l),f=Math.min(h,d),m=Math.max(h,d);if(!(a.maxX+e<u||p+e<a.minX||a.maxY+e<f||m+e<a.minY))for(let t=0;t<5;t++){const n=Mu(r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1],s,h,l,d);if(n<o){c+=(e-Math.sqrt(n))**2,n<1e-18&&(c+=20*o)}}}return c}tracesIntersect(t,e){const n=this.traces[t],s=this.traces[e],o=15,i=new Float64Array(32),r=new Float64Array(32);bu(n.waypointPair.start.x,n.waypointPair.start.y,n.ctrl1.x,n.ctrl1.y,n.ctrl2.x,n.ctrl2.y,n.waypointPair.end.x,n.waypointPair.end.y,i,o),bu(s.waypointPair.start.x,s.waypointPair.start.y,s.ctrl1.x,s.ctrl1.y,s.ctrl2.x,s.ctrl2.y,s.waypointPair.end.x,s.waypointPair.end.y,r,o);for(let t=0;t<o;t++){const e=i[2*t],n=i[2*t+1],s=i[2*(t+1)],a=i[2*(t+1)+1];for(let t=0;t<o;t++){if(Nu(e,n,s,a,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]))return!0}}return!1}findIntersectingPairs(){const t=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX<r.minX||r.maxX<i.minX||i.maxY<r.minY||r.maxY<i.minY||this.tracesIntersect(e,n)&&t.push([e,n])}return t}resolveIntersections(){const{bounds:t,preferredTraceToTraceSpacing:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=Math.min(s-n,i-o),a=.02*r,c=1.5*r,h=this.findIntersectingPairs();if(0===h.length)return 0;let l=0;for(const[t,n]of h){const s=this.traces[t],o=this.traces[n];if(!this.tracesIntersect(t,n))continue;let i,r;if(s.containedBy.includes(n))i=n,r=t;else if(o.containedBy.includes(t))i=t,r=n;else{(s.d1+s.d2)/2<(o.d1+o.d2)/2?(i=t,r=n):(i=n,r=t)}const h=this.traces[i],d=this.traces[r],u=h.d1,p=h.d2,f=d.d1,m=d.d2,g=2*e,y=[{innerMult:1,outerMult:0},{innerMult:0,outerMult:1},{innerMult:.5,outerMult:.5},{innerMult:2,outerMult:0},{innerMult:1,outerMult:1},{innerMult:3,outerMult:0},{innerMult:2,outerMult:1},{innerMult:4,outerMult:0}];let x=this.computeTotalCost(),v=null;for(const t of y)if(h.d1=u,h.d2=p,d.d1=f,d.d2=m,d.d1=Math.min(c,f+g*t.innerMult),d.d2=Math.min(c,m+g*t.innerMult),h.d1=Math.max(a,u-g*t.outerMult),h.d2=Math.max(a,p-g*t.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),!this.tracesIntersect(i,r)){const e=this.computeTotalCost();(null===v||e<x)&&(x=e,v=t)}v?(d.d1=Math.min(c,f+g*v.innerMult),d.d2=Math.min(c,m+g*v.innerMult),h.d1=Math.max(a,u-g*v.outerMult),h.d2=Math.max(a,p-g*v.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),l++):(h.d1=u,h.d2=p,d.d1=f,d.d2=m,this.updateControlPointsFromDistances(i),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(i),this.updateSingleTraceSample(r))}return l}optimizeStep(){const{bounds:t}=this.problem,{minX:e,maxX:n,minY:s,maxY:o}=t,i=Math.min(n-e,o-s),r=this.effectiveTraceToTraceSpacing,a=4*(1-this.optimizationStep/this.maxOptimizationSteps)+.5,c=.02*i,h=1.5*i,l=[];for(let t=0;t<this.traces.length;t++)l.push({idx:t,cost:this.computeCostForTrace(t)});l.sort((t,e)=>e.cost-t.cost);for(const{idx:t,cost:e}of l){if(0===e)continue;const n=this.traces[t],s=e>100?2:1,o=[a*s,1.5*a*s,.5*a];for(const s of o){const o=e>100?[s,-s,2*s,2*-s,3*s,3*-s,2*r,2*-r]:[s,-s,2*s,2*-s];let i=this.computeCostForTrace(t),a=n.d1,l=n.d2;const d=n.d1,u=n.d2;for(const e of o){n.d1=Math.max(c,Math.min(h,d+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const s=this.computeCostForTrace(t);s<i&&(i=s,a=n.d1,l=u),n.d1=d,this.updateControlPointsFromDistances(t),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const o=this.computeCostForTrace(t);o<i&&(i=o,a=d,l=n.d2),n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const r=this.computeCostForTrace(t);r<i&&(i=r,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u-e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const p=this.computeCostForTrace(t);p<i&&(i=p,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t)}if(n.d1=a,n.d2=l,this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t),i<.9*e)break}}this.optimizationStep%10==0&&this.updateCollisionPairs()}buildOutputTraces(){this.outputTraces=this.traces.map(t=>({waypointPair:t.waypointPair,points:Pu(t.waypointPair.start,t.ctrl1,t.ctrl2,t.waypointPair.end,20),networkId:t.networkId}))}_step(){if(0===this.traces.length&&(this.effectiveTraceToTraceSpacing=3*this.problem.preferredTraceToTraceSpacing,this.initializeTraces(),this.lastCost=this.computeTotalCost(),this.stagnantSteps=0),this.optimizationStep<this.maxOptimizationSteps){const t=3,e=t+(1-t)*(this.optimizationStep/this.maxOptimizationSteps);if(this.effectiveTraceToTraceSpacing=this.problem.preferredTraceToTraceSpacing*e,this.optimizeStep(),this.optimizationStep++,this.optimizationStep%10==0){this.resolveIntersections()>0&&this.updateCollisionPairs()}const n=this.computeTotalCost();if(0===n)this.optimizationStep=this.maxOptimizationSteps;else if(n>=.99*this.lastCost){if(this.stagnantSteps++,this.stagnantSteps>10){this.resolveIntersections()>0?(this.updateCollisionPairs(),this.stagnantSteps=0):this.stagnantSteps>15&&(this.optimizationStep=this.maxOptimizationSteps)}}else this.stagnantSteps=0;this.lastCost=n}this.optimizationStep>=this.maxOptimizationSteps&&(this.resolveIntersections(),this.buildOutputTraces(),this.solved=!0)}visualize(){return this.traces.length>0&&this.buildOutputTraces(),((t,e=[])=>{const n={arrows:[],circles:[],lines:[],rects:[],coordinateSystem:"cartesian",points:[],texts:[],title:"Curvy Trace Problem"};n.lines.push({points:[{x:t.bounds.minX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.minY}],strokeColor:"rgba(0, 0, 0, 0.1)"});for(const e of t.waypointPairs)n.points.push({...e.start,label:`start ${e.networkId??""}`,color:gu(e.networkId)}),n.points.push({...e.end,label:`end ${e.networkId??""}`,color:gu(e.networkId)});for(const e of t.obstacles)n.rects.push({center:e.center,width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(128, 128, 128, 0.3)",stroke:"rgba(128, 128, 128, 0.8)",label:`netId: ${e.networkId}`});for(const t of e)n.lines.push({points:t.points,strokeColor:gu(t.networkId)});return n})(this.problem,this.outputTraces)}},Tu=class extends Ln{getSolverName(){return"CurvyIntraNodeSolver"}nodeWithPortPoints;colorMap;traceWidth;viaDiameter;adjacentObstacles;routes=[];curvyTraceSolver;phase="initializing";constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaDiameter=t.viaDiameter??.3,this.adjacentObstacles=t.adjacentObstacles??[],this.MAX_ITERATIONS=1e3}_step(){switch(this.phase){case"initializing":this._initializeCurvySolver();break;case"solving":this._stepCurvySolver();break;case"done":this.solved=!0}}_initializeCurvySolver(){const t=this.nodeWithPortPoints,e={minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2},n=new Map;for(const e of t.portPoints)n.has(e.connectionName)||n.set(e.connectionName,[]),n.get(e.connectionName).push(e);const s=[];for(const[t,e]of n){if(e.length<2)continue;const n=e[0],o=e[e.length-1];s.push({start:{x:n.x,y:n.y},end:{x:o.x,y:o.y},networkId:t})}if(0===s.length)return void(this.phase="done");const o={bounds:e,waypointPairs:s,obstacles:this.adjacentObstacles.map(t=>({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},networkId:t.networkId})),preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth};this.curvyTraceSolver=new Cu(o),this.phase="solving"}_stepCurvySolver(){this.curvyTraceSolver?(this.activeSubSolver=this.curvyTraceSolver,this.curvyTraceSolver.step(),this.curvyTraceSolver.solved?(this._convertOutputTraces(),this.phase="done"):this.curvyTraceSolver.failed&&(this.error=this.curvyTraceSolver.error,this.failed=!0)):this.phase="done"}_convertOutputTraces(){if(!this.curvyTraceSolver)return;const t=this.nodeWithPortPoints,e=new Map;for(const n of t.portPoints){const t=n.connectionName;e.has(t)||e.set(t,{connectionName:n.connectionName,rootConnectionName:n.rootConnectionName,z:n.z})}for(const t of this.curvyTraceSolver.outputTraces){const n=t.networkId??"",s=e.get(n);if(!s)continue;const o={connectionName:s.connectionName,rootConnectionName:s.rootConnectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:t.points.map(t=>({x:t.x,y:t.y,z:s.z})),vias:[]};this.routes.push(o)}}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:this.adjacentObstacles}}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints;t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(0, 200, 0, 0.1)",stroke:"rgba(0, 200, 0, 0.5)",label:e.capacityMeshNodeId});for(const e of this.adjacentObstacles)t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(255, 0, 0, 0.1)",stroke:"rgba(255, 0, 0, 0.3)",label:`obstacle: ${e.networkId??""}`});if(this.curvyTraceSolver){const e=this.curvyTraceSolver.visualize();e.lines&&t.lines.push(...e.lines),e.points&&t.points.push(...e.points),e.rects&&t.rects.push(...e.rects),e.circles&&t.circles.push(...e.circles)}for(const e of this.routes){const n=this.colorMap[e.connectionName]??"gray";t.lines.push({points:e.route.map(t=>({x:t.x,y:t.y})),strokeColor:n,strokeWidth:this.traceWidth,label:e.connectionName})}for(const n of e.portPoints){const e=this.colorMap[n.connectionName]??"gray";t.points.push({x:n.x,y:n.y,color:e,label:n.connectionName})}return t}},Eu=Object.create,wu=Object.defineProperty,Ru=Object.getOwnPropertyDescriptor,Ou=Object.getOwnPropertyNames,Au=Object.getPrototypeOf,zu=Object.prototype.hasOwnProperty,Lu=(t,e)=>function(){return e||(0,t[Ou(t)[0]])((e={exports:{}}).exports,e),e.exports},Du=(t,e,n)=>(n=null!=t?Eu(Au(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Ou(e))zu.call(t,o)||o===n||wu(t,o,{get:()=>e[o],enumerable:!(s=Ru(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:wu(n,"default",{value:t,enumerable:!0}),t)),Fu=Lu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),Yu=Lu({"node_modules/kind-of/index.js"(t,e){var n=Fu(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),Xu=Lu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),ku=Lu({"node_modules/deep-rename-keys/index.js"(t,e){var n=Yu(),s=Xu();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),$u=Lu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),Bu=Lu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=$u(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),ju=Lu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=$u(),s=Bu(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:Wu,sin:Hu,PI:Uu}=Math,{tan:Vu}=Math;Du(ku()),Du(ju());function Gu(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var Zu=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function qu(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Ju=class extends Zu{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(Gu(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(Gu(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(Gu(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Ku=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Qu=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||Ku(e,n,t)>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||Ku(t,n,e)>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},tp=t=>void 0!==t,ep=class extends Zu{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(tp)),hulls:n.cells.map(t=>Qu(t,n.pts).map(t=>n.pts[t]).filter(tp))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},np=(t,e,n)=>{const s=Math.cos(n.ccwRotation),o=Math.sin(n.ccwRotation);return{x:n.center.x+t*s-e*o,y:n.center.y+t*o+e*s}},sp=(t,e=[],n,s=[])=>{const o=[],{minX:i,maxX:r,minY:a,maxY:c}=t;o.push({x:i,y:a},{x:r,y:a},{x:r,y:c},{x:i,y:c});for(let t=1;t<10;t++){const e=t/10;o.push({x:i+e*(r-i),y:a}),o.push({x:r,y:a+e*(c-a)}),o.push({x:r-e*(r-i),y:c}),o.push({x:i,y:c-e*(c-a)})}for(const t of e){const e=t.diameter/2+n;for(let n=0;n<24;n++){const s=2*Math.PI*n/24;o.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of s){const e=t.width/2+n,s=t.height/2+n,i=Math.max(2,Math.ceil(Math.max(2*e,2*s)/20));for(let n=0;n<i;n++){const r=n/i;o.push(np(2*r*e-e,-s,t)),o.push(np(e,2*r*s-s,t)),o.push(np(e-2*r*e,s,t)),o.push(np(-e,s-2*r*s,t))}}return o.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},op=class extends Zu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[];this.output={pts:sp(this.input.bounds,t,this.input.clearance,e)},this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},ip=(t,e,n)=>{const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-10)return Math.hypot(t.x-e.x,t.y-e.y);let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;return r=Math.max(0,Math.min(1,r)),Math.hypot(t.x-e.x-r*s,t.y-e.y-r*o)},rp=(t,e)=>{if(t.length<=3)return 0;const n=Qu(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,ip(t,n,s)))}i=Math.max(i,r)}return i},ap=(t,e)=>t<e?1e5*t+e:1e5*e+t,cp=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(ap(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(ap(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(ap(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},hp=(t,e)=>t<e?1e5*t+e:1e5*e+t,lp=class extends Zu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=((t,e,n)=>{if(!t.length)return{cells:[],depths:[]};const s=t.map(([t,n,s])=>{const o=e[t],i=e[n],r=e[s];return o&&i&&r&&Ku(o,i,r)<0?[t,s,n]:[t,n,s]});let o=!0,i=0;for(;o&&i++<800;){o=!1;const t=new Map,i=s.map(()=>new Set);for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let s=0;s<n.length;s++){const o=n[s],r=n[(s+1)%n.length];if(void 0===o||void 0===r)continue;const a=hp(o,r);if(t.has(a)){const n=t.get(a);void 0!==n&&(i[e]?.add(n),i[n]?.add(e))}else t.set(a,e)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<s.length;t++){const o=i[t];if(o)for(const i of o){if(i<=t)continue;const o=cp(s[t]??[],s[i]??[]);if(!o)continue;const l=rp(o,e);l<=n+1e-6&&l<h&&(h=l,r=t,a=i,c=o)}}if(r<0||a<0||!c)break;s[r]=c,s.splice(a,1),o=!0}const r=s.map(t=>rp(t,e));return{cells:s,depths:r}})(this.input.validTris,this.input.pts,this.input.concavityTolerance);this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},dp=(t,e,n)=>{const s=2*(t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y));if(Math.abs(s)<1e-10)return{x:0,y:0,r2:1e18};const o=t.x*t.x+t.y*t.y,i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=(o*(e.y-n.y)+i*(n.y-t.y)+r*(t.y-e.y))/s,c=(o*(n.x-e.x)+i*(t.x-n.x)+r*(e.x-t.x))/s;return{x:a,y:c,r2:(t.x-a)**2+(t.y-c)**2}},up=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),pp=(t,e,n,s=[],o,i=[])=>t.filter(([t,r,a])=>{const c=e[t],h=e[r],l=e[a];if(!c||!h||!l)return!1;return((t,e,n,s=[],o,i=[])=>{const{minX:r,maxX:a,minY:c,maxY:h}=n;if(t<r-.1||t>a+.1||e<c-.1||e>h+.1)return!1;for(const n of s){const s=n.diameter/2+o;if((t-n.center.x)**2+(e-n.center.y)**2<s*s-.1)return!1}for(const n of i){const s=n.width/2+o,i=n.height/2+o,r=t-n.center.x,a=e-n.center.y,c=Math.cos(n.ccwRotation),h=Math.sin(n.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<i-.1)return!1}return!0})((c.x+h.x+l.x)/3,(c.y+h.y+l.y)/3,n,s,o,i)}),fp=class extends Zu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:dp(h,l,d)}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&up(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:dp(e,n,t)})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts),s=pp(n,this.input.pts,this.input.bounds,t,this.input.clearance,e);this.output={pts:this.input.pts,validTris:s},this.stats={candidateTriangles:n.length,validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},mp=class extends Ju{pipelineDef=[qu("generatePoints",op,t=>[t.inputProblem]),qu("triangulate",fp,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,clearance:t.inputProblem.clearance}]}),qu("mergeCells",lp,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),qu("buildRegions",ep,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},gp=1e-9,yp=(t,e)=>{const n=[Op(t)],s=[];let o=e.maxSplitsPerRegion??32;for(;n.length>0;){const t=n.pop();if(!t)continue;if(t.length<4){s.push(t);continue}const i=xp(t,e);if(!i||o<=0){s.push(t);continue}const[r,a]=bp(t,i.i,i.j);o-=1,n.push(r,a)}return s},xp=(t,e)=>{const n=Sp(t);if(!n)return null;const{triangles:s}=n,o=Tp(t);if(o<=gp)return null;const i=Math.sqrt(o),r=s.map(e=>Ep(t[e[0]],t[e[1]],t[e[2]]));let a=null;for(const c of n.internalEdges){const{i:h,j:l,triA:d,triB:u}=c,p=wp(t[h],t[l])/i;if(p>e.maxNeckRatio)continue;const f=vp(d,u,s.length,n.triangleAdjacency,r),m=o-f,g=Math.min(f,m)/o;if(g<e.minSplitBalanceRatio)continue;const y=p/Math.max(g,gp);(!a||y<a.score)&&(a={i:h,j:l,score:y})}return a?{i:a.i,j:a.j}:null},vp=(t,e,n,s,o)=>{const i=new Array(n).fill(!1),r=[t];i[e]=!0;let a=0;for(;r.length>0;){const t=r.pop();if(void 0===t||i[t])continue;i[t]=!0,a+=o[t]??0;const e=s[t]??[];for(const t of e)i[t]||r.push(t)}return a},bp=(t,e,n)=>[Pp(t,e,n),Pp(t,n,e)],Pp=(t,e,n)=>{const s=[],o=t.length;let i=e;for(s.push(t[i]);i!==n;)i=(i+1)%o,s.push(t[i]);return Op(s)},Sp=t=>{const e=t.length;if(e<3)return null;const n=new Set;for(let t=0;t<e;t++){const s=(t+1)%e;n.add(Rp(t,s))}const s=Mp(t);if(!s||0===s.length)return null;const o=new Map;s.forEach((t,e)=>{for(let n=0;n<3;n++){const s=t[n],i=t[(n+1)%3],r=Rp(s,i),a=o.get(r);a?a.push(e):o.set(r,[e])}});const i=Array.from({length:s.length},()=>[]),r=[];for(const[t,e]of o.entries()){if(n.has(t))continue;if(2!==e.length)continue;const[s,o]=t.split("_"),a=Number(s),c=Number(o),h=e[0],l=e[1];r.push({i:a,j:c,triA:h,triB:l});const d=i[h],u=i[l];d&&d.push(l),u&&u.push(h)}return{triangles:s,internalEdges:r,triangleAdjacency:i}},Mp=t=>{const e=t.length;if(e<3)return null;const n=Math.sign(Cp(t));if(0===n)return null;const s=[...Array(e).keys()];n<0&&s.reverse();const o=[];let i=0;for(;s.length>3&&i<e*e;){let e=!1;for(let n=0;n<s.length;n++){const i=s[(n-1+s.length)%s.length],r=s[n],a=s[(n+1)%s.length];if(void 0===i||void 0===r||void 0===a)continue;const c=t[i],h=t[r],l=t[a];if(!c||!h||!l)continue;if(!Np(c,h,l))continue;let d=!1;for(const e of s){if(e===i||e===r||e===a)continue;const n=t[e];if(n&&Ip(n,c,h,l)){d=!0;break}}if(!d){o.push([i,r,a]),s.splice(n,1),e=!0;break}}if(!e)return null;i+=1}if(3===s.length){const[t,e,n]=s;void 0!==t&&void 0!==e&&void 0!==n&&o.push([t,e,n])}return o},Np=(t,e,n)=>_p(t,e,n)>gp,Ip=(t,e,n,s)=>{const o=_p(e,n,t),i=_p(n,s,t),r=_p(s,e,t);return o>=-1e-9&&i>=-1e-9&&r>=-1e-9},_p=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Cp=t=>{let e=0;for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];s&&o&&(e+=s.x*o.y-o.x*s.y)}return e/2},Tp=t=>Math.abs(Cp(t)),Ep=(t,e,n)=>Math.abs(_p(t,e,n))/2,wp=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),Rp=(t,e)=>t<e?`${t}_${e}`:`${e}_${t}`,Op=t=>{if(t.length<2)return t;const e=t[0],n=t[t.length-1];return e&&n&&e.x===n.x&&e.y===n.y?t.slice(0,-1):t},Ap={pattern:"grid",pitchX:2.2,pitchY:1.8,staggerAxis:"x",staggerOffset:1.1,staggerOffsetX:1.1,padWidth:.9,padHeight:1,padGap:.35,viaDiameter:.3,clearance:.2,concavityTolerance:.3,boundsPadding:1.2,orientation:"horizontal",portSpacing:.25,maxNeckRatio:0,minSplitBalanceRatio:.2},zp=(t,e)=>{let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)for(const t of r.padCenters){const r="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,a="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2;t.x-r<n&&(n=t.x-r),t.y-a<s&&(s=t.y-a),t.x+r>o&&(o=t.x+r),t.y+a>i&&(i=t.y+a)}return{minX:n-e.boundsPadding,minY:s-e.boundsPadding,maxX:o+e.boundsPadding,maxY:i+e.boundsPadding}},Lp=t=>"staggered"===t.pattern?(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++){const a="x"===t.staggerAxis&&r%2==1?t.staggerOffset:0;for(let c=0;c<t.cols;c++){const h="y"===t.staggerAxis&&c%2==1?t.staggerOffset:0,l={x:o+c*t.pitchX+a,y:i+r*t.pitchY+h},d="horizontal"===t.orientation?{x:l.x-s,y:l.y}:{x:l.x,y:l.y-s},u="horizontal"===t.orientation?{x:l.x+s,y:l.y}:{x:l.x,y:l.y+s};e.push({jumperId:`jumper_r${r}_c${c}`,center:l,orientation:t.orientation,padCenters:[d,u]}),n.push({center:d,diameter:t.viaDiameter},{center:u,diameter:t.viaDiameter})}}return{jumpers:e,vias:n,bounds:zp(e,t)}})(t):(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++)for(let a=0;a<t.cols;a++){const c={x:o+a*t.pitchX,y:i+r*t.pitchY},h="horizontal"===t.orientation?{x:c.x-s,y:c.y}:{x:c.x,y:c.y-s},l="horizontal"===t.orientation?{x:c.x+s,y:c.y}:{x:c.x,y:c.y+s},d=`jumper_r${r}_c${a}`;e.push({jumperId:d,center:c,orientation:t.orientation,padCenters:[h,l]}),n.push({center:h,diameter:t.viaDiameter},{center:l,diameter:t.viaDiameter})}return{jumpers:e,vias:n,bounds:{minX:o-s-t.padWidth/2-t.boundsPadding,maxX:o+(t.cols-1)*t.pitchX+s+t.padWidth/2+t.boundsPadding,minY:i-s-t.padHeight/2-t.boundsPadding,maxY:i+(t.rows-1)*t.pitchY+s+t.padHeight/2+t.boundsPadding}}})(t),Dp=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Fp=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],Yp=(t,e,n)=>Math.abs(t-e)<=n,Xp=(t,e,n)=>Yp(t.x,e.x,n)&&Yp(t.y,e.y,n),kp=t=>t.map((t,e)=>{const n=(t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t)i.x<e&&(e=i.x),i.y<n&&(n=i.y),i.x>s&&(s=i.x),i.y>o&&(o=i.y);return{minX:e,minY:n,maxX:s,maxY:o}})(t);return{regionId:`top_${e}`,ports:[],d:{bounds:n,center:Dp(n),polygon:t,isPad:!1}}}),$p=t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y;return Math.hypot(e,n)},Bp=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),jp=(t,e,n)=>{const s=[];if(!t.d.polygon||!e.d.polygon)return s;for(let o=0;o<t.d.polygon.length;o++){const i=t.d.polygon[o],r=t.d.polygon[(o+1)%t.d.polygon.length];if(i&&r)for(let t=0;t<e.d.polygon.length;t++){const o=e.d.polygon[t],a=e.d.polygon[(t+1)%e.d.polygon.length];if(!o||!a)continue;const c=Vp({start:i,end:r},{start:o,end:a},n);if(!c)continue;s.some(t=>Up(t,c,n))||s.push(c)}}return s},Wp=(t,e)=>{const n=[];for(const s of t){let t=s,o=!0;for(;o;){o=!1;for(let s=0;s<n.length;s++){const i=n[s];if(!i)continue;const r=Hp(t,i,e);if(r){t=r,n.splice(s,1),o=!0;break}}}n.push(t)}return n},Hp=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!Yp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!Yp(s*h-o*c,0,n)||!Yp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.min(p,f),g=Math.max(p,f),y=n/Math.sqrt(a);if(m>1+y||g<0-y)return null;const x=Math.min(0,m),v=Math.max(1,g);return{start:Bp(t,x),end:Bp(t,v)}},Up=(t,e,n)=>Xp(t.start,e.start,n)&&Xp(t.end,e.end,n)||Xp(t.start,e.end,n)&&Xp(t.end,e.start,n),Vp=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!Yp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!Yp(s*h-o*c,0,n)||!Yp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.max(0,Math.min(p,f)),g=Math.min(1,Math.max(p,f));return g-m<=n/Math.sqrt(a)?null:{start:Bp(t,m),end:Bp(t,g)}},Gp=(t,e,n)=>{const s=Math.max(t.minX,e.minX),o=Math.min(t.maxX,e.maxX),i=Math.max(t.minY,e.minY),r=Math.min(t.maxY,e.maxY);return o<s-n||r<i-n?null:{minX:s,maxX:o,minY:i,maxY:r}},Zp=t=>{const e=(t=>{const e=t.orientation??Ap.orientation,n=t.staggerAxis??Ap.staggerAxis,s=t.padWidth??Ap.padWidth,o=t.padHeight??Ap.padHeight,i=t.padGap??Ap.padGap,r=t.clearance??Ap.clearance,a=t.colSpacing??t.pitchX??Ap.pitchX,c=t.rowSpacing??t.pitchY??Ap.pitchY,h=(l=s,d=o,u=i,"horizontal"===e?{x:u+2*l,y:d}:{x:d,y:u+2*l});var l,d,u;const p=r,f=((t,e,n,s,o)=>"horizontal"===t?"x"===e?o+2*n:s:"x"===e?s:o+2*n)(e,n,s,o,i)/2,m=t.staggerOffset??t.staggerOffsetX??f,g={...Ap,...t,orientation:e,staggerAxis:n,pitchX:Math.max(a,h.x+p),pitchY:Math.max(c,h.y+p),padWidth:s,padHeight:o,padGap:i,staggerOffset:m,staggerOffsetX:m,concavityTolerance:t.concavityTolerance??Ap.concavityTolerance,clearance:r,portSpacing:t.portSpacing??Ap.portSpacing,maxNeckRatio:t.maxNeckRatio??Ap.maxNeckRatio,minSplitBalanceRatio:t.minSplitBalanceRatio??Ap.minSplitBalanceRatio};if(g.cols<=0||g.rows<=0)throw new Error("rows and cols must be > 0");if(!Number.isFinite(g.portSpacing)||g.portSpacing<=0)throw new Error("portSpacing must be > 0");if(!Number.isFinite(g.maxNeckRatio)||g.maxNeckRatio<0)throw new Error("maxNeckRatio must be >= 0");if(!Number.isFinite(g.minSplitBalanceRatio)||g.minSplitBalanceRatio<0||g.minSplitBalanceRatio>.5)throw new Error("minSplitBalanceRatio must be between 0 and 0.5");return g})(t),n=Lp(e),s="horizontal"===e.orientation?e.padWidth:e.padHeight,o="horizontal"===e.orientation?e.padHeight:e.padWidth,i=n.jumpers.flatMap(t=>t.padCenters.map(t=>({center:t,width:s,height:o,ccwRotation:0}))),r=new mp({bounds:n.bounds,rects:i,clearance:0,concavityTolerance:e.concavityTolerance});r.solve();const a=r.getOutput();if(!a)throw new Error(r.error??"ConvexRegionsSolver failed");const c=((t,e)=>{if(e.maxNeckRatio<=0)return t;const n=[];for(const s of t)n.push(...yp(s,e));return n})(a.regions,{maxNeckRatio:e.maxNeckRatio,minSplitBalanceRatio:e.minSplitBalanceRatio}),h=kp(c),l=((t,e)=>t.flatMap(t=>{const[n,s]=t.padCenters,o="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,i="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2,r={minX:n.x-o,maxX:n.x+o,minY:n.y-i,maxY:n.y+i},a={minX:s.x-o,maxX:s.x+o,minY:s.y-i,maxY:s.y+i},c=o/2,h=i/2,l="horizontal"===e.orientation?{minX:Math.min(n.x,s.x),maxX:Math.max(n.x,s.x),minY:t.center.y-h,maxY:t.center.y+h}:{minX:t.center.x-c,maxX:t.center.x+c,minY:Math.min(n.y,s.y),maxY:Math.max(n.y,s.y)};return[{regionId:`${t.jumperId}_pad1`,ports:[],d:{bounds:r,center:n,polygon:Fp(r),isPad:!0,isThroughJumper:!1}},{regionId:`${t.jumperId}_bridge`,ports:[],d:{bounds:l,center:t.center,polygon:Fp(l),isPad:!1,isThroughJumper:!0}},{regionId:`${t.jumperId}_pad2`,ports:[],d:{bounds:a,center:s,polygon:Fp(a),isPad:!0,isThroughJumper:!1}}]}))(n.jumpers,{orientation:e.orientation,padWidth:e.padWidth,padHeight:e.padHeight}),d=((t,e,n=1e-5)=>{const s=[];let o=0;for(let i=0;i<t.length;i++){const r=t[i];if(r?.d.polygon)for(let a=i+1;a<t.length;a++){const i=t[a];if(!i?.d.polygon)continue;const c=jp(r,i,n);for(const t of c){const n=$p(t),a=Math.floor(n/e),c=Math.max(1,a-1);for(let e=0;e<c;e++){const n=Bp(t,(e+1)/(c+1));s.push({portId:"tp_"+o++,region1:r,region2:i,d:{x:n.x,y:n.y}})}}}}return s})(h,e.portSpacing),u=((t,e,n=1e-5)=>{const s=[];let o=0,i=0;const r=t.filter(t=>t.d.isPad),a=t.filter(t=>t.d.isThroughJumper&&!t.d.isPad);for(const t of r)for(const i of e){const e=jp(t,i,n),r=Wp(e,n);for(const e of r){const n=Bp(e,.5);s.push({portId:"jp_"+o++,region1:t,region2:i,d:{x:n.x,y:n.y}})}}for(const t of a)for(const e of r){const o=Gp(t.d.bounds,e.d.bounds,n);if(!o)continue;const r=Dp(o);s.push({portId:"jip_"+i++,region1:e,region2:t,d:{x:r.x,y:r.y}})}return s})(l,h),p=[...d,...u];return(t=>{for(const e of t)e.region1.ports.push(e),e.region2.ports.push(e)})(p),{regions:[...h,...l],ports:p,jumperLocations:n.jumpers.map((t,e)=>({center:t.center,orientation:t.orientation,padRegions:[l[3*e],l[3*e+2]].filter(t=>Boolean(t))})),topLayerRegions:h,jumperRegions:l,jumpers:n.jumpers,vias:n.vias,bounds:n.bounds}},qp=class extends Ln{getSolverName(){return"JumperPrepatternSolver2_HyperGraph"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;hyperParameters;jumperGraphSolver=null;xyConnections=[];graphBounds=null;jumperLocations=[];solvedRoutes=[];jumpers=[];phase="jumperGraph";curvySolvers=[];currentCurvySolverIndex=0;routeInfos=[];regionCurvedPaths=new Map;constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.hyperParameters=t.hyperParameters??{},this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=this._buildColorMap())}getConstructorParams(){return this.constructorParams}_buildColorMap(){const t=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],e={},n=new Set;for(const t of this.nodeWithPortPoints.portPoints)n.add(t.connectionName);let s=0;for(const o of Array.from(n))e[o]=t[s%t.length],s++;return e}_normalizeRegionPolygonsToBounds(t){for(const e of t.regions){const t=e.d,n=t?.polygon,s=t?.bounds;if(!n||0===n.length||!s)continue;let o=1/0,i=1/0;for(const t of n)o=Math.min(o,t.x),i=Math.min(i,t.y);const r=s.minX-o,a=s.minY-i;(Math.abs(r)>1e-12||Math.abs(a)>1e-12)&&(t.polygon=n.map(t=>({x:t.x+r,y:t.y+a}))),t.polygonPerimeterCache&&(t.polygonPerimeterCache=void 0)}return t}_getPatternConfig(){return{cols:this.hyperParameters.COLS??1,rows:this.hyperParameters.ROWS??1}}_generate0603Grid(t,e,n,s){const o="horizontal"===e?t.rows:t.cols,i="horizontal"===e?t.cols:t.rows,r=s.maxX-s.minX,a=s.maxY-s.minY,c=.35,h=this.hyperParameters.TRACE_CHANNELS_BETWEEN_JUMPERS??1,l=this.traceWidth*h+2*this.obstacleMargin,d="horizontal"===e?2.15:1,u="horizontal"===e?1:2.15,p="horizontal"===e?"x":"y",f="staggered"===n,m=f&&"x"===p?d/2:f?u/2:0,g=Math.max(0,r-1),x=Math.max(0,a-1),v=Math.max(0,g-(f&&"x"===p?m:0)),b=Math.max(0,x-(f&&"y"===p?m:0)),P=o>1?Math.max(d+l,(v-d)/(o-1)):d,S=i>1?Math.max(u+l,(b-u)/(i-1)):u,M=Zp({cols:o,rows:i,orientation:e,pattern:n,staggerAxis:p,colSpacing:P,rowSpacing:S,padWidth:.9,padHeight:1,padGap:c,clearance:l,boundsPadding:0,maxNeckRatio:.4,minSplitBalanceRatio:.2}),N=M.bounds,I=(N.minX+N.maxX)/2,_=(N.minY+N.maxY)/2,C=y((s.minX+s.maxX)/2-I,(s.minY+s.maxY)/2-_);return this._normalizeRegionPolygonsToBounds(Co(M,C))}_initializeGraph(){const t=this.nodeWithPortPoints,e=this._getPatternConfig(),n=this.hyperParameters.ORIENTATION??"vertical",s=this.hyperParameters.JUMPER_TYPE??"1206x4",o=this.hyperParameters.PATTERN??"grid",i={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};let r;if(this.graphBounds=i,"0603"===s){const t=this._generate0603Grid(e,n,o,i);if(!t)return this.error=`0603 grid (${e.cols}x${e.rows}) is too large to fit in node bounds`,this.failed=!0,!1;r=t}else r=ii({cols:e.cols,rows:e.rows,marginX:Math.max(1.2,.3*e.cols),marginY:Math.max(1.2,.3*e.rows),outerPaddingX:.4,outerPaddingY:.4,parallelTracesUnderJumperCount:2,innerColChannelPointCount:3,innerRowChannelPointCount:3,outerChannelXPointCount:3,outerChannelYPointCount:3,regionsBetweenPads:!0,orientation:n,bounds:i});if(r.regions.length>0){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(const s of r.regions){if(!s.d?.isPad)continue;const i=s.d?.bounds;i&&(t=Math.min(t,i.minX),e=Math.max(e,i.maxX),n=Math.min(n,i.minY),o=Math.max(o,i.maxY))}const a="0603"===s?.5:1;if(t-a<i.minX||e+a>i.maxX||n-a<i.minY||o+a>i.maxY)return this.error=`baseGraph bounds (${t.toFixed(2)}, ${n.toFixed(2)}, ${e.toFixed(2)}, ${o.toFixed(2)}) exceed node bounds (${i.minX.toFixed(2)}, ${i.minY.toFixed(2)}, ${i.maxX.toFixed(2)}, ${i.maxY.toFixed(2)})`,this.failed=!0,!1}this.jumperLocations=r.jumperLocations?.map(t=>({center:t.center,orientation:t.orientation,padRegions:t.padRegions}))??[];const a=new Map;for(const e of t.portPoints){const t=a.get(e.connectionName);t?t.points.push(e):a.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.xyConnections=[];for(const[t,e]of Array.from(a.entries()))e.points.length<2||this.xyConnections.push({start:{x:e.points[0].x,y:e.points[0].y},end:{x:e.points[1].x,y:e.points[1].y},connectionId:t});if(0===this.xyConnections.length)return this.solved=!0,!0;const c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[],i=Io(t.regions);for(const r of e){const{start:e,end:a,connectionId:c}=r,h=Jo(`conn:${c}:start`,e.x,e.y);n.push(h);const l=Jo(`conn:${c}:end`,a.x,a.y);n.push(l);const d=si(e.x,e.y,t.regions,i);if(d){const t=qo(`conn:${c}:start-port`,h,d.region,d.portPosition);s.push(t)}const u=si(a.x,a.y,t.regions,i);if(u){const t=qo(`conn:${c}:end-port`,l,u.region,u.portPosition);s.push(t)}const p={connectionId:c,mutuallyConnectedNetworkId:c,startRegion:h,endRegion:l};o.push(p)}return{regions:n,ports:s,connections:o}})(r,this.xyConnections);return this.jumperGraphSolver=new Zo({inputGraph:{regions:c.regions,ports:c.ports},inputConnections:c.connections}),this.jumperGraphSolver.MAX_ITERATIONS*=3,!0}_step(){switch(this.phase){case"jumperGraph":this._stepJumperGraph();break;case"curvyTrace":this._stepCurvyTrace();break;case"done":this.solved=!0}}_stepJumperGraph(){if(!this.jumperGraphSolver){if(this._initializeGraph(),this.solved)return;if(!this.jumperGraphSolver)return void(this.failed=!0)}this.activeSubSolver=this.jumperGraphSolver,this.jumperGraphSolver.step(),this.jumperGraphSolver.solved?(this._initializeCurvyTraceSolvers(),this.curvySolvers.length>0?this.phase="curvyTrace":(this._finalizeCurvyTraceResults(),this.phase="done",this.solved=!0)):this.jumperGraphSolver.failed&&(this.error=this.jumperGraphSolver.error,this.failed=!0)}_stepCurvyTrace(){if(this.currentCurvySolverIndex>=this.curvySolvers.length)return this._finalizeCurvyTraceResults(),this.phase="done",void(this.solved=!0);const t=this.curvySolvers[this.currentCurvySolverIndex],e=t.solver;if(this.activeSubSolver=e,e.step(),e.solved){const n=t.regionId;this.regionCurvedPaths.has(n)||this.regionCurvedPaths.set(n,new Map);for(const t of e.outputTraces){const e=t.networkId??"",s=t.points.map(t=>({x:t.x,y:t.y})),o={path:s,start:s[0]??{x:0,y:0},end:s[s.length-1]??{x:0,y:0}};this.regionCurvedPaths.get(n).has(e)||this.regionCurvedPaths.get(n).set(e,[]),this.regionCurvedPaths.get(n).get(e).push(o)}this.currentCurvySolverIndex++}else e.failed&&this.currentCurvySolverIndex++}_initializeCurvyTraceSolvers(){if(!this.jumperGraphSolver)return;const t=new Set,e=[];for(const t of this.jumperLocations)for(const n of t.padRegions){const t=n.d.bounds,s=n.d.center;e.push({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:s.x,y:s.y},networkIds:[]})}const n=new Map;for(let e=0;e<this.jumperGraphSolver.solvedRoutes.length;e++){const s=this.jumperGraphSolver.solvedRoutes[e],o=s.connection.connectionId,i=this.nodeWithPortPoints.portPoints.find(t=>t.connectionName===o)?.rootConnectionName,r=[],a=[];let c=null,h=null;for(let l=0;l<s.path.length;l++){const d=s.path[l],u=d.port,p=d.lastRegion,f=u.region1,m=u.region2;let g;if(p)f&&f.regionId!==p.regionId?g=f:m&&m.regionId!==p.regionId&&(g=m);else{const t=s.path[l+1],e=t?.lastRegion;if(e&&(f&&f.regionId===e.regionId?g=f:m&&m.regionId===e.regionId&&(g=m)),!g){const t=t=>t?.regionId?.startsWith("conn:");g=!f||t(f)||f.d?.isPad||f.d?.isThroughJumper?!m||t(m)||m.d?.isPad||m.d?.isThroughJumper?!f||f.d?.isPad||f.d?.isThroughJumper?(!m||m.d?.isPad||m.d?.isThroughJumper)&&f||m:f:m:f}}if(g&&(!c||g.regionId!==c.regionId)){if(c&&h){a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:u});const t=c.regionId;n.has(t)||n.set(t,[]),n.get(t).push({regionId:c.regionId,region:c,routeIndex:e,connectionName:o,rootConnectionName:i,entryPort:h,exitPort:u})}c=g,h=u}if(p?.d?.isThroughJumper&&!t.has(p.regionId)){t.add(p.regionId);const e=p.d.bounds,n=p.d.center,s=e.maxX-e.minX>e.maxY-e.minY,o="0603"===(this.hyperParameters.JUMPER_TYPE??"1206x4")?"0603":"1206x4_pair";s?r.push({route_type:"jumper",start:{x:e.minX,y:n.y},end:{x:e.maxX,y:n.y},footprint:o}):r.push({route_type:"jumper",start:{x:n.x,y:e.minY},end:{x:n.x,y:e.maxY},footprint:o})}}if(c&&h){const t=s.path[s.path.length-1];a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:t?.port||null})}this.routeInfos.push({connectionId:o,rootConnectionName:i,jumpers:r,traversals:a})}for(let t=0;t<this.routeInfos.length;t++){const n=this.routeInfos[t],s=n.rootConnectionName??n.connectionId;for(const t of n.jumpers){const n=[t.start,t.end];for(const t of n)for(const n of e){const e=Math.abs(n.center.x-t.x),o=Math.abs(n.center.y-t.y);e<.1&&o<.1&&(n.networkIds.includes(s)||n.networkIds.push(s))}}}for(const[t,s]of n){if(0===s.length)continue;const n=s[0].region;if(n.d.isPad||n.d.isThroughJumper)continue;const o=n.d.bounds,i=[];for(const t of s)i.push({start:{x:t.entryPort.d.x,y:t.entryPort.d.y},end:{x:t.exitPort.d.x,y:t.exitPort.d.y},networkId:t.rootConnectionName??t.connectionName});const r=.01,a=e.filter(t=>t.minX<=o.maxX+r&&t.maxX>=o.minX-r&&t.minY<=o.maxY+r&&t.maxY>=o.minY-r).map(t=>{const e=s.map(t=>t.rootConnectionName??t.connectionName),n=t.networkIds.find(t=>e.includes(t));return{minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:t.center,networkId:n}}),c={bounds:o,waypointPairs:i,obstacles:a,preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth},h=new Cu(c);this.curvySolvers.push({solver:h,regionId:t,traversals:s.map(t=>({routeIndex:t.routeIndex,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName}))})}}_finalizeCurvyTraceResults(){const t=(t,e)=>Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2);for(let e=0;e<this.routeInfos.length;e++){const n=this.routeInfos[e],s=[];for(const e of n.traversals){const o=e.regionId,i=n.rootConnectionName??n.connectionId,r=this.regionCurvedPaths.get(o)?.get(i);let a=null;if(r&&r.length>0){const n={x:e.entryPort.d.x,y:e.entryPort.d.y},s=e.exitPort?{x:e.exitPort.d.x,y:e.exitPort.d.y}:null;let o=null,i=1/0;for(const e of r){const r=t(e.start,n)+(s?t(e.end,s):0);r<i&&(i=r,o=e)}o&&i<.5&&(a=o.path)}if(a&&a.length>0){for(let t=s.length>0?1:0;t<a.length;t++)s.push({x:a[t].x,y:a[t].y,z:0})}else 0===s.length&&s.push({x:e.entryPort.d.x,y:e.entryPort.d.y,z:0}),e.exitPort&&s.push({x:e.exitPort.d.x,y:e.exitPort.d.y,z:0})}this.solvedRoutes.push({connectionName:n.connectionId,rootConnectionName:n.rootConnectionName,traceThickness:this.traceWidth,route:s,jumpers:n.jumpers})}}getOutput(){return this.solvedRoutes}getOutputJumpers(){if(this.jumpers.length>0)return this.jumpers;const t=new Map;for(const e of this.solvedRoutes)for(const n of e.jumpers){const s=[n.start,n.end];for(const n of s){const s=`${n.x.toFixed(3)},${n.y.toFixed(3)}`,o=t.get(s)??[];e.rootConnectionName&&!o.includes(e.rootConnectionName)&&o.push(e.rootConnectionName),o.includes(e.connectionName)||o.push(e.connectionName),t.set(s,o)}}const e=this.hyperParameters.JUMPER_TYPE??"1206x4",n=En["0603"===e?"0603":"1206x4_pair"];for(const s of this.jumperLocations){const o="horizontal"===s.orientation,i=s.padRegions.map(e=>{const n=e.d.bounds,s=e.d.center,o=n.maxX-n.minX,i=n.maxY-n.minY,r=`${s.x.toFixed(3)},${s.y.toFixed(3)}`;return{type:"rect",center:s,width:o,height:i,layers:["top"],connectedTo:[...t.get(r)??[]]}}),r={jumper_footprint:e,center:s.center,orientation:s.orientation,width:o?n.length:n.width,height:o?n.width:n.length,pads:i};this.jumpers.push(r)}return this.jumpers=this.jumpers.filter(t=>t.pads.some(t=>t.connectedTo.length>0)),this.jumpers}visualize(){if(this.jumperGraphSolver&&!this.solved)return this.jumperGraphSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints,n={minX:e.center.x-e.width/2,maxX:e.center.x+e.width/2,minY:e.center.y-e.height/2,maxY:e.center.y+e.height/2};t.lines.push({points:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY},{x:n.minX,y:n.minY}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"});for(const n of e.portPoints)t.points.push({x:n.x,y:n.y,label:n.connectionName,color:this.colorMap[n.connectionName]??"blue"});for(const e of this.solvedRoutes){const n=this.colorMap[e.connectionName]??"blue";for(let s=0;s<e.route.length-1;s++){const o=e.route[s],i=e.route[s+1];t.lines.push({points:[o,i],strokeColor:Nn(n,.2),strokeWidth:e.traceThickness,layer:"route-layer-0"})}for(const s of e.jumpers)this._drawJumperPads(t,s,Nn(n,.5))}return t}_drawJumperPads(t,e,n){const s=En[e.footprint],o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)>Math.abs(i),a=r?s.padLength:s.padWidth,c=r?s.padWidth:s.padLength;t.rects.push({center:{x:e.start.x,y:e.start.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*s.padWidth,layer:"jumper-body"})}},Jp=class extends os{constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;connMap;baseHyperParameters;availableJumperTypes;solvedRoutes=[];jumpers=[];constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.connMap=t.connMap,this.baseHyperParameters=t.hyperParameters??{},this.availableJumperTypes=t.availableJumperTypes??["0603"],this.MAX_ITERATIONS=1e6,this.GREEDY_MULTIPLIER=1,this.MIN_SUBSTEPS=1e3}getConstructorParams(){return this.constructorParams}getHyperParameterDefs(){const t=[],e=this.nodeWithPortPoints,n=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1);t.push({name:"0603_max_rows_and_cols_vert_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:n.cols,ROWS:n.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const s=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1,"staggered");t.push({name:"0603_max_rows_and_cols_vert_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:s.cols,ROWS:s.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const o=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2);t.push({name:"0603_max_rows_and_cols_vert_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:o.cols,ROWS:o.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const i=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2,"staggered");t.push({name:"0603_max_rows_and_cols_vert_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:i.cols,ROWS:i.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const r=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1);t.push({name:"0603_max_rows_and_cols_horz_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:r.cols,ROWS:r.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const a=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1,"staggered");t.push({name:"0603_max_rows_and_cols_horz_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:a.cols,ROWS:a.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const c=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2);t.push({name:"0603_max_rows_and_cols_horz_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:c.cols,ROWS:c.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const h=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2,"staggered");t.push({name:"0603_max_rows_and_cols_horz_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:h.cols,ROWS:h.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]}),t.push({name:"1206x4",possibleValues:[{JUMPER_TYPE:"1206x4"}]});return t.push({name:"1206x4_cols",possibleValues:[1,2,3,4,6,8,10].map(t=>({COLS:t}))}),t.push({name:"1206x4_rows",possibleValues:[1,2,3,4,8].map(t=>({ROWS:t}))}),t.push({name:"orientation",possibleValues:[{ORIENTATION:"vertical"},{ORIENTATION:"horizontal"}]}),t}isValidCombination(t){const{JUMPER_TYPE:e,COLS:n,ROWS:s}=t,o=[1,2,4,6,8],i=[1,2,3,4,6,8,10],r=[1,2,3,4,8];return"0603"===e?o.includes(n)&&o.includes(s):"1206x4"===e&&(i.includes(n)&&r.includes(s))}getCombinationDefs(){return[["0603_max_rows_and_cols_vert_1trace_grid"],["0603_max_rows_and_cols_vert_1trace_staggered"],["0603_max_rows_and_cols_horz_1trace_grid"],["0603_max_rows_and_cols_horz_1trace_staggered"],["0603_max_rows_and_cols_vert_2trace_grid"],["0603_max_rows_and_cols_vert_2trace_staggered"],["0603_max_rows_and_cols_horz_2trace_grid"],["0603_max_rows_and_cols_horz_2trace_staggered"],["1206x4","1206x4_cols","1206x4_rows","orientation"]]}calculateMax0603ConfigWithTraceChannels(t,e,n,s,o="grid"){const i=this.traceWidth*s+2*this.obstacleMargin,r="horizontal"===n?2.15:1,a="horizontal"===n?1:2.15,c="horizontal"===n?"x":"y",h="staggered"===o&&"x"===c?r/2:"staggered"===o?a/2:0,l=Math.max(0,t-1),d=Math.max(0,e-1),u=Math.max(0,l-("staggered"===o&&"x"===c?h:0)),p=Math.max(0,d-("staggered"===o&&"y"===c?h:0)),f=r+i,m=a+i,g=Math.max(1,Math.floor(1+(u-r)/f)),y=Math.max(1,Math.floor(1+(p-a)/m));return"vertical"===n?{cols:g,rows:y}:{cols:y,rows:g}}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs();this.supervisedSolvers=[];for(const n of e){const e=n.some(t=>t.startsWith("0603_max_rows_and_cols_")),s=n.includes("1206x4");if(e&&!this.availableJumperTypes.includes("0603"))continue;if(s&&!this.availableJumperTypes.includes("1206x4"))continue;const o=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of o){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){return new qp({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,hyperParameters:{COLS:t.COLS,ROWS:t.ROWS,ORIENTATION:t.ORIENTATION,JUMPER_TYPE:t.JUMPER_TYPE,PATTERN:t.PATTERN,TRACE_CHANNELS_BETWEEN_JUMPERS:t.TRACE_CHANNELS_BETWEEN_JUMPERS},obstacleMargin:this.obstacleMargin})}computeG(t){const e=t.hyperParameters.COLS*t.hyperParameters.ROWS;return t.iterations/1e4+.25*e}computeH(t){return 1-(t.progress||0)}onSolve(t){this.solvedRoutes=t.solver.solvedRoutes,this.jumpers=t.solver.getOutputJumpers()}getOutput(){return this.solvedRoutes}getOutputJumpers(){return this.jumpers}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function Kp(t){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:0,route:t.route,vias:[],jumpers:t.jumpers}}var Qp=class extends Ln{getSolverName(){return"JumperHighDensitySolver"}allNodes;nodeAnalyses;routes;colorMap;traceWidth;obstacleMargin;viaDiameter;connMap;hyperParameters;availableJumperTypes;capacityMeshNodes;capacityMeshEdges;capacityMeshNodeMap;nodeAdjacencyMap;nodesWithoutCrossings;nodesWithCrossings;curvyIntraNodeSolvers;currentCurvySolverIndex;jumperSolvers;currentJumperSolverIndex;phase;jumpers=[];constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.15,obstacleMargin:s=.15,viaDiameter:o=.3,connMap:i,hyperParameters:r,capacityMeshNodes:a=[],capacityMeshEdges:c=[],availableJumperTypes:h}){super(),this.allNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.obstacleMargin=s,this.viaDiameter=o,this.connMap=i,this.hyperParameters=r,this.capacityMeshNodes=a,this.capacityMeshEdges=c,this.availableJumperTypes=h??["0603"],this.capacityMeshNodeMap=new Map(a.map(t=>[t.capacityMeshNodeId,t])),this.nodeAdjacencyMap=this._buildNodeAdjacencyMap(),this.nodesWithoutCrossings=[],this.nodesWithCrossings=[],this.nodeAnalyses=[],this.curvyIntraNodeSolvers=[],this.currentCurvySolverIndex=0,this.jumperSolvers=[],this.currentJumperSolverIndex=0,this.phase="analyzing",this._analyzeNodes();const l=1e3*this.nodesWithoutCrossings.length,d=1e5*this.nodesWithCrossings.length;this.MAX_ITERATIONS=l+d+100}_buildNodeAdjacencyMap(){const t=new Map;for(const e of this.capacityMeshEdges){const[n,s]=e.nodeIds;t.has(n)||t.set(n,new Set),t.has(s)||t.set(s,new Set),t.get(n).add(s),t.get(s).add(n)}return t}_analyzeNodes(){for(const t of this.allNodes){const e=yh(t),n={node:t,hasCrossings:e.numSameLayerCrossings>0,numSameLayerCrossings:e.numSameLayerCrossings};this.nodeAnalyses.push(n),e.numSameLayerCrossings>0?this.nodesWithCrossings.push(t):this.nodesWithoutCrossings.push(t)}this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done"}_step(){switch(this.phase){case"analyzing":this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done";break;case"curvy":this._stepCurvySolvers();break;case"jumpers":this._stepJumperSolvers();break;case"done":this.solved=!0}}_getAdjacentObstacles(t){const e=[],n=this.nodeAdjacencyMap.get(t.capacityMeshNodeId);if(!n||0===n.size)return e;const s=new Map(this.allNodes.map(t=>[t.capacityMeshNodeId,t]));for(const t of n){const n=this.capacityMeshNodeMap.get(t);if(!n)continue;if(!n._containsObstacle&&!n._containsTarget)continue;const o=n.center.x-n.width/2,i=n.center.y-n.height/2,r=n.center.x+n.width/2,a=n.center.y+n.height/2;let c;if(n._containsTarget)if(n._targetConnectionName)c=n._targetConnectionName;else{const e=s.get(t);e&&e.portPoints.length>0&&(c=e.portPoints[0].rootConnectionName??e.portPoints[0].connectionName)}e.push({minX:o,minY:i,maxX:r,maxY:a,networkId:c})}return e}_initializeCurvySolvers(){for(const t of this.nodesWithoutCrossings){const e=this._getAdjacentObstacles(t),n=new Tu({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:e});this.curvyIntraNodeSolvers.push(n)}}_stepCurvySolvers(){if(0===this.curvyIntraNodeSolvers.length)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());const t=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];if(this.activeSubSolver=t,!t)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());if(t.step(),t.solved){this.routes.push(...t.routes),this.currentCurvySolverIndex++;for(let t=this.currentCurvySolverIndex;t<this.curvyIntraNodeSolvers.length;t++){this.curvyIntraNodeSolvers[t];const e=this.nodesWithoutCrossings[t],n=this._getAdjacentObstacles(e),s=new Tu({nodeWithPortPoints:e,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:n});this.curvyIntraNodeSolvers[t]=s}this.currentCurvySolverIndex>=this.curvyIntraNodeSolvers.length&&(this.phase=this.nodesWithCrossings.length>0?"jumpers":"done","jumpers"===this.phase&&this._initializeJumperSolvers())}else t.failed&&(this.error=`CurvyIntraNodeSolver failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}_initializeJumperSolvers(){for(const t of this.nodesWithCrossings){const e=new Jp({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,connMap:this.connMap,availableJumperTypes:this.availableJumperTypes});this.jumperSolvers.push(e)}}_stepJumperSolvers(){if(0===this.jumperSolvers.length)return this.phase="done",void(this.solved=!0);const t=this.jumperSolvers[this.currentJumperSolverIndex];if(this.activeSubSolver=t,!t)return this.phase="done",void(this.solved=!0);if(t.step(),t.solved){for(const e of t.solvedRoutes)this.routes.push(Kp(e));this.jumpers.push(...t.getOutputJumpers()),this.currentJumperSolverIndex++,this.currentJumperSolverIndex>=this.jumperSolvers.length&&(this.phase="done",this.solved=!0)}else t.failed&&(this.error=`HyperJumperPrepatternSolver2 failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}computeProgress(){const t=this.allNodes.length;if(0===t)return 1;let e=0;e+=this.currentCurvySolverIndex;const n=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];n&&(e+=n.progress),e+=this.currentJumperSolverIndex;const s=this.jumperSolvers[this.currentJumperSolverIndex];return s&&(e+=s.progress),e/t}getConstructorParams(){return{nodePortPoints:this.allNodes,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,viaDiameter:this.viaDiameter,connMap:this.connMap,hyperParameters:this.hyperParameters,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,availableJumperTypes:this.availableJumperTypes}}getOutputJumpers(){return this.jumpers}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.failed&&this.activeSubSolver)return this.activeSubSolver.visualize();if("curvy"===this.phase&&this.curvyIntraNodeSolvers[this.currentCurvySolverIndex])return this.curvyIntraNodeSolvers[this.currentCurvySolverIndex].visualize();if("jumpers"===this.phase&&this.jumperSolvers[this.currentJumperSolverIndex])return this.jumperSolvers[this.currentJumperSolverIndex].visualize();for(const e of this.routes){const n=e.rootConnectionName??e.connectionName,s=jn(e.route,e.connectionName,this.colorMap[n]);for(const n of s)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:Nn(n.color??"gray",.75),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?"10, 5":void 0});for(const s of e.vias)t.circles.push({center:s,radius:e.viaDiameter/2,fill:Nn(this.colorMap[n]??"gray",.5),layer:"via"});if("jumpers"in e&&e.jumpers)for(const s of e.jumpers){const e=this.colorMap[n]??"gray",o=s.footprint??"1206",i=En[o],r=s.end.x-s.start.x,a=s.end.y-s.start.y,c=Math.abs(r)>Math.abs(a),h=c?i.padLength:i.padWidth,l=c?i.padWidth:i.padLength;t.rects.push({center:s.start,width:h,height:l,fill:Nn(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:s.end,width:h,height:l,fill:Nn(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[s.start,s.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*i.padWidth,layer:"jumper-body"})}}for(const e of this.nodeAnalyses){const n=e.node;n.center.x,n.width,n.center.x,n.width,n.center.y,n.height,n.center.y,n.height;t.rects.push({center:n.center,width:n.width,height:n.height,fill:e.hasCrossings?"rgba(255, 200, 0, 0.1)":"rgba(0, 200, 0, 0.1)",stroke:e.hasCrossings?"rgba(255, 150, 0, 0.5)":"rgba(0, 150, 0, 0.5)",label:[n.capacityMeshNodeId,e.hasCrossings?`crossings: ${e.numSameLayerCrossings}`:"no crossings"].join("\n")})}return t}};function tf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var ef=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline3"}netToPointPairsSolver;traceKeepoutSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[tf("netToPointPairsSolver",jh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),tf("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),tf("relateNodesToOffBoardConnections",Yd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),tf("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),tf("availableSegmentPointSolver",Fn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),tf("portPointPathingSolver",Ah,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:10*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!0,NODE_PF_FACTOR:100,MAX_RIPS:100*t.effort,RIPPING_ENABLED:!0,MAX_RIPPING_PF_THRESHOLD:.9,MIN_RIPPING_PF_THRESHOLD:.1,RANDOM_RIP_FRACTION:.05,NODE_PF_MAX_PENALTY:1e3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Ud({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),tf("highDensitySolver",Qp,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,connMap:t.connMap,capacityMeshNodes:t.capacityNodes??[],capacityMeshEdges:t.capacityEdges??[],availableJumperTypes:t.srj.availableJumperTypes}]),tf("highDensityStitchSolver",Zd,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,connectionPathResults:t.multiSectionPortPointOptimizer?.connectionResults??t.portPointPathingSolver?.connectionsWithResults??[],colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),tf("traceKeepoutSolver",Fd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??t.highDensityStitchSolver?.mergedHdRoutes??[],obstacles:t.srj.obstacles,jumpers:t.highDensitySolver?.getOutputJumpers()??[],connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.traceKeepoutSolver?.visualize(),a=this.deadEndSolver?.visualize(),c=this.availableSegmentPointSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.portPointPathingSolver?.visualize(),d=this.multiSectionPortPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensitySolver?.visualize(),f=this.simpleHighDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.traceSimplificationSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,a,c,h,l,d,u?Bn(b,u):null,p?Bn(b,p):null,f?Bn(b,f):null,m,g,r,y,this.solved?Bn(b,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`;s.obstacleId=o;const i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputJumpers(){return this.highDensitySolver?this.highDensitySolver.getOutputJumpers():[]}getOutputSimpleRouteJson(){const t=this.getOutputJumpers();return{...this.srj,traces:this.getOutputSimplifiedPcbTraces(),jumpers:t.length>0?t:void 0}}};function nf({path:t,connection:e,assignedPortPoints:n,nodeAssignedPortPoints:s}){const o=[];for(const i of t){if(!i.portPoint)continue;const t=i.portPoint;n.set(t.portPointId,{connectionName:e.name,rootConnectionName:e.rootConnectionName});const r={portPointId:t.portPointId,x:t.x,y:t.y,z:t.z,connectionName:e.name,rootConnectionName:e.rootConnectionName};o.push(r);for(const e of t.connectionNodeIds){const t=s.get(e)??[];t.push(r),s.set(e,t)}}return o}function sf(t,e){return t.x>=e.center.x-e.width/2&&t.x<=e.center.x+e.width/2&&t.y>=e.center.y-e.height/2&&t.y<=e.center.y+e.height/2}function of({connectionPoint:t,node:e}){const n=Tn(t);if(0===n.length)return console.error("[addConnectionEndpointsToNodeAssignments] endpoint has no declared layers; falling back to candidate z"),[];const s=n.map(t=>function({layerName:t,node:e}){const n=Math.max(...e.availableZ,0)+1,s=wn(t,n);if(Number.isFinite(s))return s;const o=t.match(/^layer(\d+)$/);return o?Number.parseInt(o[1],10)-1:void 0}({layerName:t,node:e})).filter(t=>void 0!==t);return 0===s.length&&console.error(`[addConnectionEndpointsToNodeAssignments] endpoint has unparseable layer names: ${n.join(", ")}; falling back to candidate z`),s}function rf({connectionPoint:t,candidate:e,node:n,endpointName:s,connection:o}){if(!n)return console.error(`[addConnectionEndpointsToNodeAssignments] ${s} endpoint for "${o.name}" missing node; using raw endpoint/candidate values`),{x:t.x,y:t.y,z:e.z};const i=function({connectionPoint:t,candidate:e,node:n,endpointName:s,connection:o}){const i=of({connectionPoint:t,node:n});if(0===i.length)return e.z;if(i.includes(e.z))return e.z;const r=i.reduce((t,n)=>Math.abs(n-e.z)<Math.abs(t-e.z)?n:t);return console.assert(!1,`[addConnectionEndpointsToNodeAssignments] ${s} endpoint for "${o.name}" is on z=${e.z} but endpoint allows z in [${i.join(", ")}]; using fallback z=${r}`),console.error(`[addConnectionEndpointsToNodeAssignments] ${s} endpoint for "${o.name}" layer mismatch; using fallback z=${r}`),r}({connectionPoint:t,candidate:e,node:n,endpointName:s,connection:o}),r=function({point:t,node:e}){return sf(t,e)}({point:t,node:n});if(!r){const e=function({point:t,node:e}){const n=e.center.x-e.width/2,s=e.center.x+e.width/2,o=e.center.y-e.height/2,i=e.center.y+e.height/2;return{x:Math.min(Math.max(t.x,n),s),y:Math.min(Math.max(t.y,o),i)}}({point:t,node:n});return console.assert(r,`[addConnectionEndpointsToNodeAssignments] ${s} endpoint for "${o.name}" connectionPoint outside obstacle/node bounds; original=(${t.x}, ${t.y}) clamped=(${e.x}, ${e.y})`),{x:e.x,y:e.y,z:i}}return{x:t.x,y:t.y,z:i}}function af({path:t,connection:e,inputNodeMap:n,nodeAssignedPortPoints:s}){if(0===t.length)return;const o=t[0],i=t[t.length-1],r=e.pointsToConnect[0],a=e.pointsToConnect[e.pointsToConnect.length-1];if(r){const t=rf({connectionPoint:r,candidate:o,node:n.get(o.currentNodeId),endpointName:"start",connection:e}),i=s.get(o.currentNodeId)??[];i.push({x:t.x,y:t.y,z:t.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),s.set(o.currentNodeId,i)}if(a){const t=rf({connectionPoint:a,candidate:i,node:n.get(i.currentNodeId),endpointName:"end",connection:e}),o=s.get(i.currentNodeId)??[];o.push({x:t.x,y:t.y,z:t.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),s.set(i.currentNodeId,o)}}function cf({candidate:t}){return t.nextRegion?.regionId?t.nextRegion.regionId:t.port.region2?.regionId?t.port.region2.regionId:t.port.region1.regionId}function hf({solvedRoute:t,connectionResult:e,layerCount:n}){const s=[],o=e.connection,i=o.pointsToConnect[0],r=o.pointsToConnect[o.pointsToConnect.length-1],a=i?wn(Cn(i),n):0,c=r?wn(Cn(r),n):0,h={prevCandidate:null,portPoint:null,currentNodeId:e.nodeIds[0],point:{x:i?.x??0,y:i?.y??0},z:a,f:0,g:0,h:0,distanceTraveled:0};s.push(h);for(const e of t.path){const t=s[s.length-1],n=e.port.d,o={prevCandidate:t,portPoint:n,currentNodeId:cf({candidate:e}),point:{x:n.x,y:n.y},z:n.z,f:0,g:0,h:0,distanceTraveled:t.distanceTraveled+k(t.point,n)};s.push(o)}const l=s[s.length-1],d={prevCandidate:l,portPoint:null,currentNodeId:e.nodeIds[1],point:{x:r?.x??l.point.x,y:r?.y??l.point.y},z:c,f:0,g:0,h:0,distanceTraveled:l.distanceTraveled+k(l.point,r??l.point)};return s.push(d),s}function lf({solvedRoutes:t,connectionResults:e,inputNodes:n,layerCount:s}){const o=new Map(e.map(t=>[t.connection.name,t])),i=new Map,r=new Map,a=new Map(n.map(t=>[t.capacityMeshNodeId,t]));for(const t of n)r.set(t.capacityMeshNodeId,[]);for(const e of t){const t=e.connection.connectionId,n=o.get(t);if(!n)continue;const c=hf({solvedRoute:e,connectionResult:n,layerCount:s});n.path=c,n.portPoints=nf({path:c,connection:n.connection,assignedPortPoints:i,nodeAssignedPortPoints:r}),af({path:c,connection:n.connection,inputNodeMap:a,nodeAssignedPortPoints:r})}return{connectionsWithResults:e,assignedPortPoints:i,nodeAssignedPortPoints:r}}var df=t=>{const e=function({solver:t}){const e=[],n=[],s=[],o=[];for(const e of t.inputNodes){const n=t.computeNodePf(e),s=Math.min(255,Math.floor(512*n)),i=Math.max(0,255-Math.floor(512*n));let r=`rgba(${s}, ${i}, ${i}, ${n<.001?"0.1":"0.3"})`;e._containsObstacle&&(r="rgba(255, 0, 0, 0.3)"),e._offBoardConnectedCapacityMeshNodeIds?.length&&(r="rgba(255, 165, 0, 0.3)"),o.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(80, 80, 120, 0.15)",fill:r,label:`${e.capacityMeshNodeId}\npf: ${n.toFixed(3)}`})}for(const e of t.portPointMap.values())n.push({center:{x:e.x,y:e.y},radius:.035,fill:"rgba(120, 120, 120, 0.3)"});for(const n of t.graph.ports){const t=n.region1.d.center,s=n.region2.d.center;e.push({points:[t,{x:n.d.x,y:n.d.y},s],strokeColor:"rgba(100, 100, 100, 0.1)",strokeWidth:.03})}for(const n of t.connections){const t=n.startRegion.d.center,o=n.endRegion.d.center,i=(t.x+o.x)/2,r=(t.y+o.y)/2;e.push({points:[t,o],strokeColor:"rgba(255, 50, 150, 0.2)",strokeWidth:.05}),s.push({x:i,y:r,color:"rgba(200, 0, 100, 0.9)",label:n.connectionId})}return{lines:e,circles:n,points:s,rects:o}}({solver:t});if(t.currentConnection&&!t.solved){const n=In(t.currentConnection.connectionId,.8),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i=s.d.center,r=o.d.center;e.lines.push({points:[i,r],strokeColor:n,strokeDash:"10 5"}),e.points.push({x:i.x-.1,y:i.y+.1,color:n,label:[t.currentConnection.connectionId,"start"].join("\n")}),e.points.push({x:r.x-.1,y:r.y+.1,color:n,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const n of t.solvedRoutes){const t=In(n.connection.connectionId,.8),s=[];for(const t of n.path){const e=t.port;s.push({x:e.d.x,y:e.d.y})}const o=n.connection.startRegion.d.center,i=n.connection.endRegion.d.center;s.unshift(o),s.push(i),s.length>0&&e.lines.push({points:s,strokeColor:t})}const n=t.candidateQueue.peekMany(10);for(let t=0;t<n.length;t++){const s=n[t],o=s.port,i=0===t;e.points.push({x:o.d.x,y:o.d.y,color:i?"green":"rgba(128, 128, 128, 0.55)",label:[s.port.portId,`g: ${s.g.toFixed(2)}`,`h: ${s.h.toFixed(2)}`,`f: ${s.f.toFixed(2)}`].join("\n")})}const s=n[0];if(!t.solved&&s&&t.currentConnection){const n=In(t.currentConnection.connectionId,.8),o=[];let i=s;for(;i;){const t=i.port;o.unshift({x:t.d.x,y:t.d.y}),i=i.parent}const r=t.currentConnection.startRegion.d.center;o.unshift(r),o.length>1&&e.lines.push({points:o,strokeColor:n})}return e},uf=class extends go{inputNodes;regionNodeMap;regionById;portPointMap;connectionsWithResults=[];assignedPortPoints=new Map;nodeAssignedPortPoints=new Map;assignmentsBuilt=!1;portUsagePenalty;regionTransitionPenalty;ripRegionPfThresholdStart;maxRegionRips;memoryPfFactor;centerOffsetDistPenaltyFactor;forceCenterFirst;straightLineDeviationPenaltyFactor;connectionResultByName;regionRipCountMap=new Map;regionMemoryPfMap=new Map;totalRipCount=0;randomRipFraction;maxRips;MIN_ALLOWED_BOARD_SCORE;layerCount;constructor({inputGraph:t,inputConnections:e,connectionsWithResults:n,inputNodes:s,portPointMap:o,regionMemoryPfMap:i,rippingEnabled:r,weights:a,forceCenterFirst:c,layerCount:h}){const{GREEDY_MULTIPLIER:l,MAX_REGION_RIPS:d,MEMORY_PF_FACTOR:u,CENTER_OFFSET_DIST_PENALTY_FACTOR:p,PORT_USAGE_PENALTY:f,REGION_TRANSITION_PENALTY:m,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:g,RIP_COST:y,RIP_REGION_PF_THRESHOLD_START:x,RANDOM_RIP_FRACTION:v,MAX_RIPS:b,MIN_ALLOWED_BOARD_SCORE:P}=a;super({inputGraph:t,inputConnections:e,greedyMultiplier:l,rippingEnabled:r??!0,ripCost:y}),this.inputNodes=s,this.regionNodeMap=new Map(s.map(t=>[t.capacityMeshNodeId,t])),this.regionById=new Map(this.graph.regions.map(t=>[t.regionId,t])),this.portPointMap=o,this.connectionsWithResults=n,this.portUsagePenalty=f,this.regionTransitionPenalty=m,this.ripRegionPfThresholdStart=x,this.maxRegionRips=d,this.memoryPfFactor=u,this.centerOffsetDistPenaltyFactor=p,this.forceCenterFirst=c,this.straightLineDeviationPenaltyFactor=g,this.regionMemoryPfMap=i,this.randomRipFraction=v,this.maxRips=b,this.MIN_ALLOWED_BOARD_SCORE=P,this.MAX_ITERATIONS=2e5,this.connectionResultByName=new Map(n.map(t=>[t.connection.name,t])),this.layerCount=h}clampPf(t){return Number.isFinite(t)?Math.max(0,Math.min(.9999,t)):0}pfToFailureCost(t){return-Math.log(1-this.clampPf(t))}recordRegionMemoryPf(t,e){const n=this.clampPf(e),s=this.regionMemoryPfMap.get(t)??0,o=Math.max(n,.98*s);this.regionMemoryPfMap.set(t,o)}estimateCostToEnd(t){const e=this.currentEndRegion?.d?.center;return e?k({x:t.d.x,y:t.d.y},e):0}computeH(t){const e=this.estimateCostToEnd(t.port),n=t.port.d.distToCentermostPortOnZ??0,s=t.nextRegion?.regionId??t.lastRegion?.regionId,o=s?this.regionMemoryPfMap.get(s)??0:0,i=this.pfToFailureCost(o)*this.memoryPfFactor,r=this.getStraightLineDeviationPenalty(t);return e+n*this.centerOffsetDistPenaltyFactor+i+r}getStraightLineDeviationPenalty(t){if(this.straightLineDeviationPenaltyFactor<=0)return 0;const e=this.currentConnection?.connectionId;if(!e)return 0;const n=this.connectionResultByName.get(e),s=n?.connection.pointsToConnect;if(!s||s.length<2)return 0;const o=s[0],i=s[1],r=X({x:t.port.d.x,y:t.port.d.y},o,i);return this.straightLineDeviationPenaltyFactor*r}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){const s=k({x:e.d.x,y:e.d.y},{x:n.d.x,y:n.d.y}),o=.01*Math.max(t.d.width,t.d.height);return s*this.regionTransitionPenalty+o}getPortUsagePenalty(t){return(t.ripCount??0)*this.portUsagePenalty}getRipsRequiredForPortUsage(t,e,n){const s=t.assignments??[];if(0===s.length)return[];const o={x:e.d.x,y:e.d.y},i={x:n.d.x,y:n.d.y};return s.filter(t=>{if(t.connection.mutuallyConnectedNetworkId===this.currentConnection?.mutuallyConnectedNetworkId)return!1;const s=t.regionPort1,r=t.regionPort2;if(s===e||s===n)return!1;if(r===e||r===n)return!1;const a={x:s.d.x,y:s.d.y},c={x:r.d.x,y:r.d.y};return D(o,i,a,c)})}isPortAvailableForCurrentNet(t){const e=t.assignment;if(!e)return!0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n}getCenterFirstEnteringRegionCandidates(t){const e=new Map;for(const n of t){const t=n.port.d.z??0,s=e.get(t)??[];s.push(n),e.set(t,s)}const n=[];for(const t of e.values()){const e=t.slice().sort((t,e)=>t.port.d.distToCentermostPortOnZ-e.port.d.distToCentermostPortOnZ)[0];if(!e)continue;if(this.isPortAvailableForCurrentNet(e.port)){n.push(e);continue}const s=t.slice().sort((t,e)=>t.port.d.x!==e.port.d.x?t.port.d.x-e.port.d.x:t.port.d.y-e.port.d.y),o=[];let i=[];for(const t of s)this.isPortAvailableForCurrentNet(t.port)?i.push(t):i.length>0&&(o.push(i),i=[]);i.length>0&&o.push(i);for(const t of o)n.push(t[Math.floor(t.length/2)])}return n}selectCandidatesForEnteringRegion(t){const e=this.currentConnection?.startRegion,n=this.currentConnection?.endRegion,s=t.filter(t=>{const s=t.nextRegion;return!s?.d._containsObstacle||(s===e||s===n)}),o=this.forceCenterFirst?this.getCenterFirstEnteringRegionCandidates(s):s;return o.length<=2?o:o.slice().sort((t,e)=>t.g+t.h-(e.g+e.h)).slice(0,2)}routeSolvedHook(t){const e=new Set;for(const n of t.path){const t=n.lastRegion;t&&e.add(t)}for(const t of e){const e=this.computeRegionPfFromAssignments(t);this.recordRegionMemoryPf(t.regionId,e)}if(!t.requiredRip)return;if(this.unprocessedConnections.length<2)return;const[n,...s]=this.unprocessedConnections;this.unprocessedConnections=[...s,n]}_step(){super._step(),this.enforceBoardScoreGuardrail()||this.buildAssignmentsIfSolved()}enforceBoardScoreGuardrail(){if(!this.solved||this.failed)return!1;const t=this.computeBoardScore();return this.stats={...this.stats,boardScore:t,totalRipCount:this.totalRipCount},!(t>=this.MIN_ALLOWED_BOARD_SCORE)&&(this.error=`Board score ${t.toFixed(2)} is less than MIN_ALLOWED_BOARD_SCORE ${this.MIN_ALLOWED_BOARD_SCORE.toFixed(2)}`,this.failed=!0,this.solved=!1,!0)}buildAssignmentsIfSolved(){if(!this.solved||this.assignmentsBuilt)return;const t=lf({solvedRoutes:this.solvedRoutes,connectionResults:this.connectionsWithResults,inputNodes:this.inputNodes,layerCount:this.layerCount});this.connectionsWithResults=t.connectionsWithResults,this.assignedPortPoints=t.assignedPortPoints,this.nodeAssignedPortPoints=t.nodeAssignedPortPoints,this.assignmentsBuilt=!0}getRegionRippingPfThreshold(t){const e=this.regionRipCountMap.get(t)??0,n=Math.min(1,e/this.maxRegionRips);return this.ripRegionPfThresholdStart*(1-n)+1*n}getPortPointsFromRegionAssignments(t){return t.flatMap(t=>{const e=t.regionPort1,n=t.regionPort2,s=t.connection.connectionId,o=t.connection.mutuallyConnectedNetworkId;return[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:s,rootConnectionName:o},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:s,rootConnectionName:o}]})}getPortPointsFromNewlySolvedRouteInRegion(t,e){return t.path.flatMap(n=>{if(!n.lastPort||n.lastRegion!==e)return[];const s=n.lastPort,o=n.port;return[{x:s.d.x,y:s.d.y,z:s.d.z,connectionName:t.connection.connectionId,rootConnectionName:t.connection.mutuallyConnectedNetworkId},{x:o.d.x,y:o.d.y,z:o.d.z,connectionName:t.connection.connectionId,rootConnectionName:t.connection.mutuallyConnectedNetworkId}]})}computeRegionPf({region:t,newlySolvedRoute:e,routesToRip:n}){const s=this.regionNodeMap.get(t.regionId);if(!s||s._containsTarget)return 0;const o=(t.assignments??[]).filter(t=>!n.has(t.solvedRoute)),i=[...this.getPortPointsFromRegionAssignments(o),...this.getPortPointsFromNewlySolvedRouteInRegion(e,t)],r={capacityMeshNodeId:s.capacityMeshNodeId,center:s.center,width:s.width,height:s.height,portPoints:i,availableZ:s.availableZ},a=yh(r),c=this.getDerivedCapacityMeshNode(s);return bh(c,a.numSameLayerCrossings,a.numEntryExitLayerChanges,a.numTransitionPairCrossings)}computeRegionPfFromAssignments(t){const e=this.regionNodeMap.get(t.regionId);if(!e||e._containsTarget)return 0;const n=t.assignments??[],s=this.getPortPointsFromRegionAssignments(n),o={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:s,availableZ:e.availableZ},i=yh(o),r=this.getDerivedCapacityMeshNode(e);return bh(r,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings)}getDerivedCapacityMeshNode(t){return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,availableZ:t.availableZ,layer:`z${t.availableZ.join(",")}`,_containsObstacle:t._containsObstacle,_containsTarget:t._containsTarget,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds}}getCrossingRoutesByRegionForRoute(t){const e=new Map;for(const n of t.path){if(!n.lastPort||!n.lastRegion)continue;const t=n.lastRegion,s=t.regionId,o=this.getRipsRequiredForPortUsage(t,n.lastPort,n.port);if(0===o.length)continue;const i=e.get(s)??new Set;for(const t of o)i.add(t.solvedRoute);e.set(s,i)}return e}getRoutesInRegionForRipping({regionId:t,routesToRip:e,newlySolvedRoute:n}){const s=this.regionById.get(t);if(!s?.assignments?.length)return[];const o=new Map;for(const t of s.assignments){const s=t.solvedRoute,i=s.connection.connectionId;i!==n.connection.connectionId&&(e.has(s)||o.set(i,s))}return[...o.values()]}getTraversedRegionIds(t){const e=new Set;for(const n of t.path){const t=n.lastRegion;t&&e.add(t.regionId)}return[...e]}processRandomRips({routesToRip:t,newlySolvedRoute:e,randomSeed:n}){if(this.randomRipFraction<=0)return;if(this.totalRipCount>=this.maxRips)return;const s=this.solvedRoutes.filter(n=>!t.has(n)&&n.connection.connectionId!==e.connection.connectionId);if(0===s.length)return;const o=Math.max(1,Math.floor(this.randomRipFraction*s.length)),i=Vn(s,n);let r=0;for(const e of i){if(r>=o)break;if(this.totalRipCount>=this.maxRips)break;t.has(e)||(t.add(e),r++,this.totalRipCount++)}}processRippingForRoute(t){const e=super.computePortOverlapRoutes(t),n=new Set(e),s=this.getCrossingRoutesByRegionForRoute(t),o=this.iterations+this.solvedRoutes.length+this.totalRipCount,i=this.getTraversedRegionIds(t),r=Vn(Array.from(new Set([...i,...s.keys()])),o);for(const e of r){if(this.totalRipCount>=this.maxRips)break;const s=this.regionById.get(e);if(!s)continue;const i=this.getRegionRippingPfThreshold(e);let r=this.computeRegionPf({region:s,newlySolvedRoute:t,routesToRip:n});if(this.recordRegionMemoryPf(e,r),r<=i)continue;const a=new Set;let c=0;for(;r>i&&!(this.totalRipCount>=this.maxRips);){const i=this.getRoutesInRegionForRipping({regionId:e,routesToRip:n,newlySolvedRoute:t}).filter(t=>!a.has(t.connection.connectionId)&&!n.has(t));if(0===i.length)break;const h=Vn(i,o+c+a.size)[0];if(!h)break;a.add(h.connection.connectionId),n.add(h),this.totalRipCount++,c++,this.regionRipCountMap.set(e,(this.regionRipCountMap.get(e)??0)+1),r=this.computeRegionPf({region:s,newlySolvedRoute:t,routesToRip:n}),this.recordRegionMemoryPf(e,r)}}return n.size>e.size&&this.processRandomRips({routesToRip:n,newlySolvedRoute:t,randomSeed:o+1e4}),n}computeRoutesToRip(t){return this.processRippingForRoute(t)}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];0!==n.length&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}computeBoardScore(){let t=this.nodeAssignedPortPoints;if(!this.assignmentsBuilt){t=lf({solvedRoutes:this.solvedRoutes,connectionResults:this.connectionsWithResults,inputNodes:this.inputNodes,layerCount:this.layerCount}).nodeAssignedPortPoints}const e=[];for(const n of this.inputNodes){const s=t.get(n.capacityMeshNodeId)??[];0!==s.length&&e.push({capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:s,availableZ:n.availableZ})}return Ph(e,new Map(this.inputNodes.map(t=>[t.capacityMeshNodeId,this.getDerivedCapacityMeshNode(t)])))}computeNodePf(t){const e=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId);if(!e||0===e.length)return 0;const n={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:e,availableZ:t.availableZ},s=yh(n),o=this.getDerivedCapacityMeshNode(t);return bh(o,s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}visualize(){return df(this)}};var pf=t=>{const{candidates:e,mapOfCapacityMeshNodeIdToRef:n}=t;let s=!0;for(const t of e){let e=!1;t.port.nodeIds.forEach(t=>{const s=n.get(t);if(!s)throw new Error(`Could not find capacity mesh node for id ${t}`);s._containsObstacle&&(e=!0)}),e||(s=!1)}return s},ff=t=>t.depth+1e3*t.countOfCrampedPortPointsInPath,mf=class extends N{constructor(t){if(super(),this.input=t,this.input.depthLimit<1)throw new Error("Depth limit must be at least 1");this._setup()}queue=[];resultExploredPortPoints=[];currentExploredPortPoints=null;visitedExploredPortPoints=[];getSolverName(){return"singleTargetNecessaryCrampedPortPointSolver"}_setup(){const t=this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(this.input.target.capacityMeshNodeId)??[];for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:1,parent:null,countOfCrampedPortPointsInPath:e.cramped?1:0};this.queue.push(t)}this.visitedExploredPortPoints=[...new Set(this.queue.map(t=>t.port))]}_step(){if(0===this.queue.length)return this.currentExploredPortPoints=null,void(this.solved=!0);for(;this.queue.length>0;){if(this.currentExploredPortPoints=this.queue.shift(),this.currentExploredPortPoints.depth===this.input.depthLimit){this.resultExploredPortPoints.push(this.currentExploredPortPoints);continue}const t=this.currentExploredPortPoints.port.nodeIds.map(t=>{const e=this.input.mapOfCapacityMeshNodeIdToRef.get(t);if(!e)throw new Error(`Could not find capacity mesh node for id ${t}`);return e}).flatMap(t=>this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(t.capacityMeshNodeId)??[]);for(const e of t)this.input.shouldIgnoreCrampedPortPoints&&e.cramped||this.queue.push({port:e,depth:this.currentExploredPortPoints.depth+1,parent:this.currentExploredPortPoints,countOfCrampedPortPointsInPath:this.currentExploredPortPoints.countOfCrampedPortPointsInPath+(e.cramped?1:0)})}this.visitedExploredPortPoints=[...new Set(this.queue.map(t=>t.port)),...this.visitedExploredPortPoints],this.solved=!0}getOutput(){return this.resultExploredPortPoints}visualize(){const t={points:[],rects:[]};for(const e of this.visitedExploredPortPoints)t.points.push({...e,color:e.cramped?"blue":"green"});return t}},gf=class extends N{constructor(t){super(),this.input=t,this._setup()}unprocessedTargets=[];targetNode=[];currentTarget;crampedPortPointsToKeep=new Set;candidatesAtDepth=[];isRunningCrampedPass=!1;activeSubSolver=null;nodeMap=new Map;mapOfCapacityMeshNodeIdToSegmentPortPoints=new Map;getSolverName(){return"multiTargetNecessaryCrampedPortPointSolver"}_setup(){this.targetNode=this.input.capacityMeshNodes.filter(t=>t._containsObstacle);const t=this.input.simpleRouteJson.connections.flatMap(t=>t.pointsToConnect);this.targetNode=this.targetNode.filter(e=>{let n=!1;return t.forEach(t=>{(function(t,e){const n=e.width/2,s=e.height/2,o=e.center.x-n,i=e.center.x+n,r=e.center.y-s,a=e.center.y+s;return t.x>=o&&t.x<=i&&t.y>=r&&t.y<=a?0:k(t,{x:L(t.x,o,i),y:L(t.y,r,a)})})(t,e)<=0&&(n=!0)}),n}),this.unprocessedTargets=[...this.targetNode],this.unprocessedTargets.sort((t,e)=>t.center.x-e.center.x);for(const t of this.input.capacityMeshNodes)this.nodeMap.set(t.capacityMeshNodeId,t);for(const t of this.input.sharedEdgeSegments)for(const e of t.portPoints){const t=e.nodeIds;for(const n of t){if(!this.nodeMap.get(n))throw new Error(`Could not find capacity mesh node for id ${n}`);const t=this.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(n)||[];this.mapOfCapacityMeshNodeIdToSegmentPortPoints.set(n,[...t,e])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver._step(),!this.activeSubSolver.solved)return;if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error);if(this.candidatesAtDepth=this.activeSubSolver.getOutput(),this.activeSubSolver=null,!this.currentTarget)return this.failed=!0,void(this.error="Missing current capacity mesh node while finishing BFS");if(!this.isRunningCrampedPass){return pf({candidates:this.candidatesAtDepth,mapOfCapacityMeshNodeIdToRef:this.nodeMap})||0===this.candidatesAtDepth.length?(this.isRunningCrampedPass=!0,void(this.activeSubSolver=new mf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!1,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.currentTarget=void 0)}let t=this.candidatesAtDepth.filter(t=>{const e=t.port;return e.nodeIds.map(t=>{const e=this.nodeMap.get(t);if(!e)throw this.failed=!0,this.error=`Could not find capacity mesh node for id ${t}`,new Error(`Could not find capacity mesh node for id ${t}`);return e}).every(t=>!t._containsObstacle)&&e.cramped});pf({candidates:t,mapOfCapacityMeshNodeIdToRef:this.nodeMap})&&(this.error=`All candidates are blocked by obstacles even after including cramped port points for capacity mesh node ${this.currentTarget.capacityMeshNodeId}`),this.candidatesAtDepth=[...t].sort((t,e)=>ff(t)-ff(e));const e=this.candidatesAtDepth[0];return e&&0!==t.length?this.crampedPortPointsToKeep.add(e.port):this.error=`No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`,this.isRunningCrampedPass=!1,void(this.currentTarget=void 0)}if(!this.currentTarget)return this.currentTarget=this.unprocessedTargets.shift(),this.currentTarget?(this.isRunningCrampedPass=!1,this.candidatesAtDepth=[],void(this.activeSubSolver=new mf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!0,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.solved=!0)}getOutput(){return this.input.sharedEdgeSegments.map(t=>({...t,portPoints:t.portPoints.filter(t=>!t.cramped||this.crampedPortPointsToKeep.has(t))}))}visualize(){const t={rects:[],points:[]};for(const e of this.targetNode)t.rects.push({...e,fill:this.currentTarget?.capacityMeshNodeId===e.capacityMeshNodeId?"rgba(255, 0, 0, 0.5)":"rgba(255, 0, 0, 0.2)"});for(const e of this.candidatesAtDepth)t.points.push({...e.port,color:e.port.cramped?"blue":"green"});for(const e of this.crampedPortPointsToKeep)t.points.push({...e,color:"blue"});return this.activeSubSolver?M(t,this.activeSubSolver.visualize()):t}};function yf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var xf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;inputNodeWithPortPoints=[];cacheProvider=null;pipelineDef=[yf("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),yf("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),yf("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),yf("availableSegmentPointSolver",Fn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),yf("necessaryCrampedPortPointSolver",gf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),yf("portPointPathingSolver",uf,t=>{this.inputNodeWithPortPoints=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle}));const e=new Map(this.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,t])),n=t.necessaryCrampedPortPointSolver;for(const t of n.getOutput())for(const n of t.portPoints){const[t,s]=n.nodeIds,o={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,s],distToCentermostPortOnZ:n.distToCentermostPortOnZ},i=e.get(t);i&&i.portPoints.push(o)}const{graph:s,regionMap:o,portPointMap:i}=function({inputNodes:t}){const e=new Map,n=new Map,s=[],o=[];for(const n of t){const t={regionId:n.capacityMeshNodeId,ports:[],assignments:[],d:n};s.push(t),e.set(n.capacityMeshNodeId,t)}for(const s of t)for(const t of s.portPoints){if(n.has(t.portPointId))continue;n.set(t.portPointId,t);const[s,i]=t.connectionNodeIds,r=e.get(s),a=e.get(i);if(!r||!a)continue;const c={portId:t.portPointId,region1:r,region2:a,d:t};o.push(c),r.ports.push(c),a.ports.push(c)}return{graph:{regions:s,ports:o},regionMap:e,portPointMap:n}}({inputNodes:this.inputNodeWithPortPoints}),{connections:r,connectionsWithResults:a}=function({simpleRouteJson:t,inputNodes:e,regionMap:n}){const{unshuffledConnectionsWithResults:s}=uh(t,e),o=[];for(const t of s){const e=n.get(t.nodeIds[0]),s=n.get(t.nodeIds[1]);if(!e||!s)throw new Error(`Missing region for connection "${t.connection.name}"`);o.push({connectionId:t.connection.name,mutuallyConnectedNetworkId:t.connection.rootConnectionName??t.connection.name,startRegion:e,endRegion:s})}return{connections:o,connectionsWithResults:s}}({simpleRouteJson:t.srjWithPointPairs,inputNodes:this.inputNodeWithPortPoints,regionMap:o});return[{inputGraph:s,inputConnections:r,connectionsWithResults:a,inputNodes:this.inputNodeWithPortPoints,portPointMap:i,rippingEnabled:!0,weights:{PORT_USAGE_PENALTY:.15,REGION_TRANSITION_PENALTY:.6,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:.05,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4,RIP_COST:8.5,GREEDY_MULTIPLIER:.7,RIP_REGION_PF_THRESHOLD_START:.3,MAX_REGION_RIPS:100,MAX_RIPS:1e3,RANDOM_RIP_FRACTION:.3,MIN_ALLOWED_BOARD_SCORE:-1e4},forceCenterFirst:!0,regionMemoryPfMap:new Map,layerCount:t.srj.layerCount}]}),yf("uniformPortDistributionSolver",Ae,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),yf("highDensityRouteSolver",dh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),yf("highDensityStitchSolver",Kh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),yf("traceSimplificationSolver",Il,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),yf("traceWidthSolver",_l,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.necessaryCrampedPortPointSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,f,c,h,l,d?Bn(y,d):null,u,p,this.solved?Bn(y,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},vf=class extends Fl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=>this.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length&&(t.width>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length>0)&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=>this.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=>t===n)&&t.push(e)}e.set(n,t)}const n=new Set;for(const t of e.values())for(const e of t)n.add(e);this.finishedNodes=this.finishedNodes.filter(t=>!n.has(t));for(const n of t){const t=e.get(n)||[],s=n.layers&&n.layers.length>0?Array.from(new Set(n.layers.map(t=>wn(t,this.srj.layerCount)))).sort((t,e)=>t-e):Array.from({length:this.srj.layerCount},(t,e)=>this.srj.layerCount-e-1);let o=n.center.x-n.width/2,i=n.center.x+n.width/2,r=n.center.y-n.height/2,a=n.center.y+n.height/2;for(const e of t){const t=e.center.x-e.width/2,n=e.center.x+e.width/2,s=e.center.y-e.height/2,c=e.center.y+e.height/2;o=Math.min(o,t),i=Math.max(i,n),r=Math.min(r,s),a=Math.max(a,c)}const c=i-o,h=a-r,l=(o+i)/2,d=(r+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x>=o&&e.x<=i&&e.y>=r&&e.y<=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===s.length?`z${s[0]}`:`z${s.join(",")}`,availableZ:s,_depth:0,_containsTarget:u,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=n,this.finishedNodes.push(p)}}_step(){const t=this.unfinishedNodes.pop();if(!t)return this.insertAssignableObstaclesAsNodes(),void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e;if(e)s.push(t);else{if(o){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget&&this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?s.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)&&!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},bf=.005,Pf=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver_OnlyMergeTargets"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n._assignedViaObstacle?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):n._containsTarget?n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]):(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId));e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new kn(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Yn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<bf&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<bf&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<bf&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<bf&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Layer Node Merger (Only Merge Targets)"};for(const e of this.newNodes)t.rects.push(Xl(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=Xl(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=Xl(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},Sf=class extends Ln{getSolverName(){return"AssignableViaNodeMergerSolver"}newNodes;obstacleToNodesMap;obstaclesToProcess;mergedNodeIds;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.newNodes=[],this.obstacleToNodesMap=new Map,this.mergedNodeIds=new Set;for(const e of t){const t=e._assignedViaObstacle;if(t){const n=this.obstacleToNodesMap.get(t)||[];n.push(e),this.obstacleToNodesMap.set(t,n)}else this.newNodes.push(e)}this.obstaclesToProcess=Array.from(this.obstacleToNodesMap.keys())}_step(){const t=this.obstaclesToProcess.pop();if(!t)return void(this.solved=!0);const e=this.obstacleToNodesMap.get(t);if(!e||0===e.length)return;let n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;const r=new Set;let a=!1;for(const t of e){const e=t.center.x-t.width/2,c=t.center.x+t.width/2,h=t.center.y-t.height/2,l=t.center.y+t.height/2;n=Math.min(n,e),s=Math.max(s,c),o=Math.min(o,h),i=Math.max(i,l);for(const e of t.availableZ)r.add(e);t._containsTarget&&(a=!0)}const c=s-n,h=i-o,l=(n+s)/2,d=(o+i)/2,u=Array.from(r).sort((t,e)=>t-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===u.length?`z${u[0]}`:`z${u.join(",")}`,availableZ:u,_containsTarget:a,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=t;for(const t of e)this.mergedNodeIds.add(t.capacityMeshNodeId);this.newNodes.push(p)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Assignable Via Node Merger"};for(const e of this.newNodes){const n=Xl(e);e._assignedViaObstacle&&(n.stroke="rgba(255, 0, 255, 0.8)",n.label=`${n.label||""}\n(merged via)`),t.rects.push(n)}const e=this.obstaclesToProcess[this.obstaclesToProcess.length-1];if(e){const n=this.obstacleToNodesMap.get(e)||[];for(const e of n){const n=Xl(e,{rectMargin:.01});n.stroke="rgba(0, 255, 0, 0.8)",n.label=`${n.label||""}\n(to be merged)`,t.rects.push(n)}}return t}},Mf=class extends Ln{constructor(t){const{simpleRouteJson:e,nodes:n,edges:s,colorMap:o,MAX_ITERATIONS:i=1e6,hyperParameters:r={}}=t;super(),this.inputParams=t,this.hyperParameters=r,this.MAX_ITERATIONS=i,this.simpleRouteJson=e,this.nodes=n,this.edges=s,this.colorMap=o??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Dn(this.edges);const a=this.nodes.filter(t=>t._containsTarget);this.unprocessedConnectionPairs=Vn(this.simpleRouteJson.connections.map(t=>{const[e,n]=t.pointsToConnect;return{start:a.find(t=>k(t.center,e)<t.width/2),end:a.find(t=>k(t.center,n)<t.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=>t.availableZ.length>1)}getSolverName(){return"AssignableViaCapacityPathingSolver_DirectiveSubOptimal"}GREEDY_MULTIPLIER=1.5;simpleRouteJson;nodes;edges;colorMap;MAX_ITERATIONS;hyperParameters;usedNodeMap=new Map;nodeMap;nodeEdgeMap;unprocessedConnectionPairs;solvedRoutes=[];activeConnectionPair=null;ogUnprocessedSubpaths=null;unprocessedSubpaths=null;solvedSubpaths=null;activeSubpath=null;viaNodes=[];closestViaForConnectionStartMap=new Map;closestViaForConnectionEndMap=new Map;getConstructorParams(){return this.inputParams}lastStepOperation="none";computeClosestViaForAllConnections(){this.closestViaForConnectionStartMap.clear(),this.closestViaForConnectionEndMap.clear();for(const t of this.unprocessedConnectionPairs){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length>0){const n=e.reduce((e,n)=>{const s=this._dist(e,t.start);return this._dist(n,t.start)<s?n:e});this.closestViaForConnectionStartMap.set(t,n);const s=e.reduce((e,n)=>{const s=this._dist(e,t.end);return this._dist(n,t.end)<s?n:e});this.closestViaForConnectionEndMap.set(t,s)}}}_step(){if(!this.activeConnectionPair)return this.activeConnectionPair=this.unprocessedConnectionPairs.shift(),this.activeConnectionPair?(this.computeClosestViaForAllConnections(),void(this.lastStepOperation="dequeueConnectionPair")):void(this.solved=!0);if(this.activeConnectionPair&&!this.unprocessedSubpaths)return this.unprocessedSubpaths=this.breakConnectionPairIntoSubpaths(this.activeConnectionPair),this.ogUnprocessedSubpaths=this.unprocessedSubpaths.slice(),this.solvedSubpaths=[],void(this.lastStepOperation="breakConnectionPairIntoSubpaths");if(this.activeSubpath){if(this.activeSubpath&&(this.stepSolveSubpath(this.activeSubpath),this.activeSubpath.solved))return this.solvedSubpaths.push(this.activeSubpath),this.activeSubpath=null,this.clearCandidateNodes(),void(this.lastStepOperation="finishedSolvingSubpath");this.lastStepOperation="stepSolveSubpath"}else{if(this.activeSubpath=this.unprocessedSubpaths.shift(),!this.activeSubpath){const t=this.activeConnectionPair;return this.activeConnectionPair=null,this.unprocessedSubpaths=null,this.ogUnprocessedSubpaths=null,this.activeSubpath=null,this.solvedRoutes.push(this.createSolvedRoute(this.solvedSubpaths,t)),void(this.lastStepOperation="finishedSolvingConnectionPair")}this.lastStepOperation="dequeueSubpath"}}queuedCandidateNodes=[];visitedNodes=new Set;_dist(t,e){return Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)}stepSolveSubpath(t){const{start:e,end:n}=t;if(e.capacityMeshNodeId===n.capacityMeshNodeId)return t.path=[e],t.solved=!0,void this.usedNodeMap.set(e.capacityMeshNodeId,!0);if(0===this.queuedCandidateNodes.length&&0===this.visitedNodes.size){const t=this._dist(e,n),s={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(s)}let s;for(this.queuedCandidateNodes.sort((t,e)=>t.f-e.f);this.queuedCandidateNodes.length&&!s;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(s=t)}if(!s)return this.failed=!0,void(this.error="No viable candidates left");if(this.visitedNodes.add(s.node.capacityMeshNodeId),s.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=s;for(;n;)e.unshift(n.node),this.usedNodeMap.set(n.node.capacityMeshNodeId,!0),n=n.prevCandidate;return t.path=e,void(t.solved=!0)}const o=this.getNeighbors(s.node);for(const t of o){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+this.GREEDY_MULTIPLIER*i,a=this.queuedCandidateNodes.findIndex(t=>t.node.capacityMeshNodeId===e);if(a>=0){if(this.queuedCandidateNodes[a].g<=o)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:s,node:t,g:o,h:i,f:r})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const s of n){const[n,o]=s.nodeIds,i=n===t.capacityMeshNodeId?o:n,r=this.nodeMap.get(i);r&&e.add(r)}const s=this.activeSubpath?.layer;return Array.from(e).filter(t=>!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle&&(!t._containsTarget&&(!this.usedNodeMap.has(t.capacityMeshNodeId)&&!(void 0!==s&&!t.availableZ.includes(s)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const s=this._dist(t.node,e);return t.g+s}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e<t.length;e++){const s=t[e];s.path?0===e?n.push(...s.path):n.push(...s.path.slice(1)):(0===e&&n.push(s.start),e===t.length-1&&n.push(s.end))}return{connection:e.connection,path:n}}breakConnectionPairIntoSubpaths(t){var e,n;if(!(e=[this.hyperParameters.DIRECTIVE_SEED??0,this.solvedRoutes.length],n=this.hyperParameters.FORCE_VIA_TRAVEL_CHANCE??0,Hn(e.reduce((t,e)=>t+16807*e%2147483647,0))()<n))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const s=this.getClosestVia(t.start),o=this.getFarVia(s,t.end),i=t.start.availableZ[0]??0,r=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:s,solved:!1,layer:i}),i===r?(a.push({start:s,end:o,solved:!1,layer:0===i?1:0}),a.push({start:o,end:t.end,solved:!1,layer:r})):a.push({start:s,end:t.end,solved:!1,layer:r}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=>!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=>this._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=>this._dist(e,t)-this._dist(n,t));const s=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(s>0&&n.length>1){const t=Hn((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(s+1));return n[Math.min(e,n.length-1)]}return n[0]}getFarVia(t,e){if(0===this.viaNodes.length)return t;const n=null!=this.hyperParameters.FAR_VIA_MIN_DISTANCE?this.hyperParameters.FAR_VIA_MIN_DISTANCE:50,s=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);const o=this.viaNodes.filter(e=>!this.usedNodeMap.has(e.capacityMeshNodeId)&&e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!s.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n);if(0===o.length){const s=this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n).sort((t,n)=>this._dist(t,e)-this._dist(n,e));if(s.length>0)return s[0];return this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=>this._dist(t,e)-this._dist(n,e))[0]??t}o.sort((t,n)=>this._dist(t,e)-this._dist(n,e));const i=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(i>0&&o.length>1){const t=Hn((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(i+1));return o[Math.min(e,o.length-1)]}return o[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n&&n.length>0&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=>!!t&&"number"==typeof t.x&&"number"==typeof t.y&&!Number.isNaN(t.x)&&!Number.isNaN(t.y)&&Number.isFinite(t.x)&&Number.isFinite(t.y),n=t=>"number"==typeof t&&!Number.isNaN(t)&&Number.isFinite(t);for(const s of this.nodes){const o=this.queuedCandidateNodes.some(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId),i=this.queuedCandidateNodes.find(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId);if(e(s.center)&&n(s.width)&&n(s.height)){const e=Xl(s,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:o?"rgba(255, 128, 255, 0.5)":s._containsTarget?"rgba(0, 150, 255, 0.15)":s._containsObstacle?"rgba(255, 0, 0, 0.1)":"rgba(200, 200, 200, 0.05)",label:[`ID: ${s.capacityMeshNodeId}`,`Size: ${s.width.toFixed(2)}x${s.height.toFixed(2)}`,`Z: ${s.availableZ.join(", ")}`,i?`g: ${i.g.toFixed(2)}`:"",i?`h: ${i.h.toFixed(2)}`:"",i?`f: ${i.f.toFixed(2)}`:"",s._containsTarget?"TARGET":"",s._containsObstacle?"OBSTACLE":""].filter(t=>t).join("\n")})}}for(const n of this.edges){const[s,o]=n.nodeIds,i=this.nodeMap.get(s),r=this.nodeMap.get(o);i?.center&&r?.center&&e(i.center)&&e(r.center)&&t.lines.push({points:[i.center,r.center],strokeColor:"rgba(150, 150, 150, 0.2)"})}for(let n=0;n<this.solvedRoutes.length;n++){const s=this.solvedRoutes[n],o=s.path,i="blue";for(let s=0;s<o.length-1;s++){const r=o[s],a=o[s+1];if(r?.center&&a?.center&&e(r.center)&&e(a.center)){const e=r.availableZ.includes(1)&&a.availableZ.includes(1),s=n%5*.02;t.lines.push({points:[{x:r.center.x+s,y:r.center.y+s},{x:a.center.x+s,y:a.center.y+s}],strokeColor:i,strokeDash:e?"5 5":void 0})}}if(o.length>0){const n=o[0],i=o[o.length-1];n?.center&&e(n.center)&&t.points.push({x:n.center.x,y:n.center.y,label:`START: ${s.connection.name}`}),i?.center&&e(i.center)&&t.points.push({x:i.center.x,y:i.center.y,label:`END: ${s.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n<this.solvedSubpaths.length;n++){const s=this.solvedSubpaths[n];if(s.path&&s.path.length>1)for(let n=0;n<s.path.length-1;n++){const o=s.path[n],i=s.path[n+1];o?.center&&i?.center&&e(o.center)&&e(i.center)&&t.lines.push({points:[o.center,i.center],strokeColor:"green",strokeDash:1===s.layer?"3 3":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,s=this.activeSubpath.end?.center;n&&s&&e(n)&&e(s)&&(t.lines.push({points:[n,s],strokeColor:"orange",strokeDash:"5 5"}),t.points.push({x:n.x,y:n.y,label:"ACTIVE START"}),t.points.push({x:s.x,y:s.y,label:"ACTIVE END"}))}const s=this.queuedCandidateNodes.slice(0,10).sort((t,e)=>t.f-e.f);for(let n=0;n<s.length;n++){const o=.6*(1-n/10),i=[];let r=s[n];for(;r;)i.push(r.node),r=r.prevCandidate;if(i.reverse(),i.length>1){const n=i.map(t=>t.center).filter(t=>e(t));n.length>1&&t.lines.push({points:n,strokeColor:Nn("purple",1-o),strokeDash:1===this.activeSubpath?.layer?"4 2":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,s=this.activeConnectionPair.end?.center;n&&s&&e(n)&&e(s)&&t.lines.push({points:[n,s],strokeColor:"cyan",strokeDash:"20 5"})}if(this.ogUnprocessedSubpaths&&3===this.ogUnprocessedSubpaths.length){const[,s]=this.ogUnprocessedSubpaths;if(s.start?.center&&e(s.start.center)){const e=Math.max(s.start.width||0,s.start.height||0);n(e)&&e>0&&(t.circles.push({center:s.start.center,radius:e,stroke:"blue"}),t.points.push({x:s.start.center.x,y:s.start.center.y,label:"DIRECTIVE VIA 1"}))}if(s.end?.center&&e(s.end.center)){const e=Math.max(s.end.width||0,s.end.height||0);n(e)&&e>0&&(t.circles.push({center:s.end.center,radius:e,stroke:"purple"}),t.points.push({x:s.end.center.x,y:s.end.center.y,label:"DIRECTIVE VIA 2"}))}}if(this.queuedCandidateNodes.length>0)for(const n of this.queuedCandidateNodes){const s=n.node;s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.05,fill:"rgba(255, 255, 0, 0.6)",stroke:"yellow"})}if(this.visitedNodes.size>0)for(const n of this.visitedNodes){const s=this.nodeMap.get(n);s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.08,fill:"rgba(128, 128, 128, 0.5)",stroke:"gray"})}return t}},Nf=class extends os{getSolverName(){return"HyperAssignableViaCapacityPathingSolver"}constructorParams;constructor(t){super(),this.constructorParams=t,this.MAX_ITERATIONS=t.MAX_ITERATIONS??12e4,this.MIN_SUBSTEPS=5,this.GREEDY_MULTIPLIER=1.35}getHyperParameterDefs(){return[{name:"traceOrderingSeed",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5},{SHUFFLE_SEED:6},{SHUFFLE_SEED:7},{SHUFFLE_SEED:8},{SHUFFLE_SEED:9}]},{name:"forceViaTravelChance",possibleValues:[{FORCE_VIA_TRAVEL_CHANCE:.6},{FORCE_VIA_TRAVEL_CHANCE:.8},{FORCE_VIA_TRAVEL_CHANCE:.9}]}]}computeG(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length,s=e>0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-s)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e>0?1-n/e:0}generateSolver(t){return new Mf({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function If(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function _f(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var Cf=class extends Ln{getSolverName(){return"OffboardCapacityNodeSolver"}capacityNodes;capacityEdges;enhancedEdges=[];animationState="showing_nodes";assignableNodes=[];shownNodes=[];pendingEdges=[];createdEdges=[];nextEdgeId=0;nodeMap=new Map;constructor(t){super(),this.capacityNodes=t.capacityNodes,this.capacityEdges=t.capacityEdges,this.nodeMap=If(this.capacityNodes),this.enhancedEdges=[...this.capacityEdges],this.initializeAssignableNodes(),this.initializePendingEdges(),this.MAX_ITERATIONS=this.assignableNodes.length+this.pendingEdges.length+10}initializeAssignableNodes(){for(const t of this.capacityNodes){const e=t._assignedViaObstacle;e?.offBoardConnectsTo&&e.offBoardConnectsTo.length>0&&this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const s of n.offBoardConnectsTo)t.has(s)||t.set(s,[]),t.get(s).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length>1)for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++)this.pendingEdges.push({node1:n[t],node2:n[s],netName:e})}_step(){switch(this.animationState){case"showing_nodes":if(this.assignableNodes.length>0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState="showing_edges";break;case"showing_edges":if(this.pendingEdges.length>0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),s=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(s),this.createdEdges.push(s)}else this.animationState="done",this.solved=!0;break;case"done":this.solved=!0}}createOffboardEdge(t,e,n){return{capacityMeshEdgeId:"offboard_"+this.nextEdgeId++,nodeIds:[t.capacityMeshNodeId,e.capacityMeshNodeId],isOffboardEdge:!0,offboardNetName:n}}visualize(){const t=[],e=[],n=[],s=new Set(this.shownNodes.map(t=>t.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(s.has(e.nodeIds[0])||s.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"rgba(0, 200, 0, 0.5)",strokeWidth:.05})}}for(let t=0;t<this.shownNodes.length;t++){const s=this.shownNodes[t],o=s._assignedViaObstacle,i=t===this.shownNodes.length-1&&"showing_nodes"===this.animationState;n.push({center:s.center,width:s.width,height:s.height,fill:i?"rgba(255, 165, 0, 0.5)":"rgba(173, 216, 230, 0.5)",stroke:i?"orange":"blue",strokeWidth:i?.15:.1}),e.push({x:s.center.x,y:s.center.y,color:i?"orange":"blue",label:`${i?"NEW: ":""}${s.capacityMeshNodeId}\n${o?.offBoardConnectsTo?.join(", ")||""}`})}for(let n=0;n<this.createdEdges.length;n++){const s=this.createdEdges[n],o=n===this.createdEdges.length-1&&"showing_edges"===this.animationState,i=this.nodeMap.get(s.nodeIds[0]),r=this.nodeMap.get(s.nodeIds[1]);if(i&&r){t.push({points:[i.center,r.center],strokeColor:o?"red":"orange",strokeWidth:o?.2:.1,strokeDasharray:"0.3,0.15"});const n=_f(i.center,r.center);e.push({x:n.x,y:n.y,color:o?"red":"orange",label:`${o?"NEW: ":""}⚡ ${s.offboardNetName}`})}}let o="Offboard Capacity Node Solver";switch(this.animationState){case"showing_nodes":o+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case"showing_edges":o+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case"done":o+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:o}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=>t.isOffboardEdge)}},Tf=class extends Ln{getSolverName(){return"OffboardPathFragmentSolver"}inputPaths;capacityEdges;originalConnections;fragmentedPaths=[];fragmentedConnections=[];fragmentedOriginalConnectionNames=new Set;nextFragmentId=0;animationState="showing_original_path";currentPath=null;currentFragments=[];currentFragmentIndex=0;nodeMap=new Map;constructor({capacityPaths:t,capacityEdges:e,capacityNodes:n,connections:s}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=s,this.nodeMap=If(n)}_step(){switch(this.animationState){case"showing_original_path":if(0===this.inputPaths.length)return this.animationState="done",void(this.solved=!0);this.currentPath=this.inputPaths.shift(),this.currentFragments=this.splitPath(this.currentPath),this.currentFragmentIndex=0;this.currentFragments.some(t=>t.isFragmentedPath)?this.animationState="showing_fragment":this.fragmentedPaths.push(...this.currentFragments);break;case"showing_fragment":if(this.currentFragmentIndex<this.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath&&(this.fragmentedOriginalConnectionNames.add(this.currentPath.connectionName),this.createFragmentConnections(this.currentPath,this.currentFragments)),this.currentPath=null,this.currentFragments=[],this.currentFragmentIndex=0,this.animationState="showing_original_path";break;case"done":this.solved=!0}}createFragmentConnections(t,e){const n=this.originalConnections.find(e=>e.name===t.connectionName);if(n)for(let t=0;t<e.length;t++){const s=e[t];if(!s.isFragmentedPath)continue;const o=n.pointsToConnect.filter(t=>{for(const e of s.nodeIds){const n=this.nodeMap.get(e);if(n&&sf(t,n))return!0}return!1}),i=0===t,r=i?s.nodeIds[s.nodeIds.length-1]:s.nodeIds[0],a=this.nodeMap.get(r);if(o.length>0&&a){const t=o[0],e={x:a.center.x,y:a.center.y,layer:Cn(t)},r=i?[...o,e]:[e,...o];this.fragmentedConnections.push({name:s.connectionName,pointsToConnect:r,netConnectionName:n.netConnectionName,rootConnectionName:n.rootConnectionName})}}}splitPath(t){const{nodeIds:e}=t;if(e.length<2)return[t];const n=[];for(let t=0;t<e.length-1;t++){const s=this.capacityEdges.find(n=>n.nodeIds[0]===e[t]&&n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]&&n.nodeIds[1]===e[t]);s&&s.isOffboardEdge&&n.push(t)}if(0===n.length)return[t];const s=[];let o=0,i=0;for(const r of n){const n=e.slice(o,r+1);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}o=r+1}if(o<e.length){const n=e.slice(o);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return s.length>0?s:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if("showing_original_path"===this.animationState&&this.currentPath&&this.drawPath({path:this.currentPath,color:"gray",lines:t,points:e,rects:n,labelPrefix:"Original: "}),this.fragmentedPaths.forEach((s,o)=>{if(s.isFragmentedPath){const i=o%2==0?"blue":"red";this.drawPath({path:s,color:i,lines:t,points:e,rects:n,labelPrefix:`Frag ${o}: `})}else this.drawPath({path:s,color:"green",lines:t,points:e,rects:n,labelPrefix:""})}),"showing_fragment"===this.animationState&&this.currentFragmentIndex>0){const s=this.fragmentedPaths.length-1;if(s>=0){const o=this.fragmentedPaths[s];o.isFragmentedPath&&this.drawPath({path:o,color:"orange",lines:t,points:e,rects:n,labelPrefix:"NEW: "})}}for(const e of this.capacityEdges)if(e.isOffboardEdge){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"orange",strokeWidth:.15,strokeDasharray:"0.3,0.15"})}let s="Offboard Path Fragment Solver";return"showing_original_path"===this.animationState?s+=" - Analyzing path...":"showing_fragment"===this.animationState?s+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:s+=` - Done (${this.fragmentedPaths.filter(t=>t.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:s}}drawPath(t){const{path:e,color:n,lines:s,points:o,rects:i,labelPrefix:r}=t,a=[];for(let t=0;t<e.nodeIds.length;t++){const s=e.nodeIds[t],c=this.nodeMap.get(s);c&&(a.push(c.center),i.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t&&t!==e.nodeIds.length-1||o.push({x:c.center.x,y:c.center.y,color:n,label:`${r}${e.connectionName}\n${s}`}))}a.length>1&&s.push({points:a,strokeColor:n,strokeWidth:.1})}};function Ef(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var wf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=vh(o,i)}this.connMap=zn(t),this.colorMap=Mn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline1Solver"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;initialPathingHyperSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;mergeAssignableViaNodes;offboardCapacityNodeSolver;offboardPathFragmentSolver;strawSolver;deadEndSolver;uselessViaRemovalSolver1;uselessViaRemovalSolver2;multiSimplifiedPathSolver1;multiSimplifiedPathSolver2;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Ef("netToPointPairsSolver",jh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Mn(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Ef("nodeSolver",vf,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),Ef("mergeAssignableViaNodes",Sf,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),Ef("singleLayerNodeMerger",Pf,t=>[t.capacityNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),Ef("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Ef("offboardCapacityNodeSolver",Cf,t=>[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=>{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),Ef("deadEndSolver",nd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),Ef("initialPathingHyperSolver",Nf,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=>{const e=t.initialPathingHyperSolver?.winningSolver;e&&(t.initialPathingSolver=e)}}),Ef("offboardPathFragmentSolver",Tf,t=>[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=>{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath&&e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n&&!t.colorMap[e.connectionName]&&(t.colorMap[e.connectionName]=n)}const s=e.getFragmentedOriginalConnectionNames(),o=e.getFragmentedConnections();s.size>0&&t.srjWithPointPairs&&(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=>!s.has(t.name)),...o]},t.connMap=zn(t.srjWithPointPairs))}}),Ef("edgeToPortSegmentSolver",wl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),Ef("segmentToPointSolver",Yl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),Ef("unravelMultiSectionSolver",xd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),Ef("highDensityRouteSolver",dh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),Ef("highDensityStitchSolver",Kh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("uselessViaRemovalSolver1",ll,t=>[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("multiSimplifiedPathSolver1",Ml,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),Ef("uselessViaRemovalSolver2",ll,t=>[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("multiSimplifiedPathSolver2",Ml,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver2?.getOptimizedHdRoutes(),obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.mergeAssignableViaNodes?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.pathingOptimizer?.visualize(),d=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),f=this.highDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),x=this.multiSimplifiedPathSolver1?.visualize(),v=this.multiSimplifiedPathSolver2?.visualize(),b=this.srj.outline,P=[];if(P.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),b&&b.length>=2){const t=b.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),P.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const S={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:P},M=[S,t,e,n,s,o,i,r,a,c,h,l,d,u,p,f?Bn(S,f):null,m,g,x,y,v,this.solved?Bn(S,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.multiSimplifiedPathSolver2?.simplifiedHdRoutes??this.uselessViaRemovalSolver2?.getOptimizedHdRoutes()??this.multiSimplifiedPathSolver1?.simplifiedHdRoutes??this.uselessViaRemovalSolver1?.getOptimizedHdRoutes()??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes(),n=this.srjWithPointPairs?.connections??[];for(const s of n){const n=s.netConnectionName,o=s.rootConnectionName,i=e.filter(t=>t.connectionName===s.name);for(let e=0;e<i.length;e++){const r=i[e],a={type:"pcb_trace",pcb_trace_id:`${s.name}_${e}`,connection_name:n??o??s.name,route:Le(r,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Rf=1.8,Of=.95,Af=.8,zf=.95,Lf=class extends Ln{getSolverName(){return"SingleHighDensityRouteWithJumpersSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;roundedGoalPosition;straightLineDistance;traceThickness;obstacleMargin;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;JUMPER_PENALTY_FACTOR;FUTURE_CONNECTION_START_END_PENALTY;FUTURE_CONNECTION_START_END_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PENALTY;JUMPER_JUMPER_PAD_PROXIMITY;JUMPER_JUMPER_PAD_PENALTY;FUTURE_CONNECTION_LINE_PROXIMITY;FUTURE_CONNECTION_LINE_PENALTY;OBSTACLE_PROX_PENALTY_FACTOR;OBSTACLE_PROX_SIGMA;EDGE_PROX_PENALTY_FACTOR;EDGE_PROX_SIGMA;ALLOW_DIAGONAL;MIN_TRAVEL_BEFORE_JUMPER;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;rootConnectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_exploredNodeValues;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;existingJumpers;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{};const e=Math.sqrt((t.bounds.maxX-t.bounds.minX)**2+(t.bounds.maxY-t.bounds.minY)**2);this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.JUMPER_PENALTY_FACTOR=.2,this.FUTURE_CONNECTION_START_END_PROXIMITY??=8,this.FUTURE_CONNECTION_START_END_PENALTY??=3,this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY??e/4,this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PENALTY??1e3,this.JUMPER_JUMPER_PAD_PROXIMITY=this.hyperParameters.JUMPER_JUMPER_PAD_PROXIMITY??5,this.JUMPER_JUMPER_PAD_PENALTY=this.hyperParameters.JUMPER_JUMPER_PAD_PENALTY??0,this.FUTURE_CONNECTION_LINE_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_LINE_PROXIMITY??10,this.FUTURE_CONNECTION_LINE_PENALTY=this.hyperParameters.FUTURE_CONNECTION_LINE_PENALTY??5,this.OBSTACLE_PROX_PENALTY_FACTOR=this.hyperParameters.OBSTACLE_PROX_PENALTY_FACTOR??2,this.OBSTACLE_PROX_SIGMA=this.hyperParameters.OBSTACLE_PROX_SIGMA??2,this.EDGE_PROX_PENALTY_FACTOR=this.hyperParameters.EDGE_PROX_PENALTY_FACTOR??1,this.EDGE_PROX_SIGMA=this.hyperParameters.EDGE_PROX_SIGMA??1,this.ALLOW_DIAGONAL=this.hyperParameters.ALLOW_DIAGONAL??!0,this.MIN_TRAVEL_BEFORE_JUMPER??=3,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.rootConnectionName=t.rootConnectionName,this.obstacleRoutes=t.obstacleRoutes,this.A={...t.A,z:0},this.B={...t.B,z:0},this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_exploredNodeValues=new Map,this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.existingJumpers=[];for(const t of this.obstacleRoutes)t.jumpers&&this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;for(;s*o>n**2&&!(this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const i=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!i&&this.handleSimpleCases();const r={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:r.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:r.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.roundedGoalPosition={x:Math.round(t.B.x/this.cellStep)*this.cellStep,y:Math.round(t.B.y/this.cellStep)*this.cellStep,z:0};const a={distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},c={distanceToGoal:0,obstacleProximity:0,edgeProximity:0,futureConnectionStartEndProximityPenalty:0,futureConnectionLine:0,total:0,obstacleProximityRate:0,edgeProximityRate:0,futureConnectionStartEndProximityRate:0,futureConnectionLineRate:0};this.candidates=new Zn([{...t.A,...r,z:0,g:0,h:0,f:0,jumperCount:0,gComponents:a,hComponents:c,parent:{...t.A,z:0,g:0,h:0,f:0,gComponents:a,hComponents:c,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this;this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return Rf+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){const s=Df(n);for(const n of s)if(X(t,n.A,n.B)<this.traceThickness+e)return!0}for(const s of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,s,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const s=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(s)>Math.abs(o),r=(i?Af:zf)/2+n,a=(i?zf:Af)/2+n;return Math.abs(t.x-e.start.x)<r&&Math.abs(t.y-e.start.y)<a||Math.abs(t.x-e.end.x)<r&&Math.abs(t.y-e.end.y)<a}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0<this.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x<this.bounds.minX+e||t.x>this.bounds.maxX-e||t.y<this.bounds.minY+e||t.y>this.bounds.maxY-e;return(!n||!(k(t,this.B)<2*e||k(t,this.A)<2*e))&&n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Df(n))if(D(t,e,s.A,s.B))return!0;for(const s of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,s))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const s=this.obstacleMargin,o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=Math.abs(o)>Math.abs(i),a=(r?Af:zf)/2+s,c=(r?zf:Af)/2+s;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,s,o){const i=n.x-s,r=n.x+s,a=n.y-o,c=n.y+o;if(t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c)return!0;if(e.x>=i&&e.x<=r&&e.y>=a&&e.y<=c)return!0;const h=[{A:{x:i,y:a},B:{x:r,y:a}},{A:{x:r,y:a},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:i,y:c}},{A:{x:i,y:c},B:{x:i,y:a}}];for(const n of h)if(D(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const s of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,s.connectionName);if(!o)for(const o of Df(s))D(t,e,o.A,o.B)&&n.push({A:o.A,B:o.B})}return n}computeHComponents(t){const e=k(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),s=this.getEdgeProximityPenalty(t),o=this.getFutureConnectionStartEndPenalty(t),i=this.getFutureConnectionLinePenalty(t),r=t.parent,a=r?.hComponents,c=r?k(t,r):0,h=(t,n)=>{if(void 0===n||c<1e-9||e<1e-9)return t;const s=(t-n)/c;return(t+Math.max(0,t+s*e))/2},l=h(n,a?.obstacleProximityRate),d=h(s,a?.edgeProximityRate),u=h(o,a?.futureConnectionStartEndProximityRate),p=h(i,a?.futureConnectionLineRate),f=l*e,m=d*e,g=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:f,edgeProximity:m,futureConnectionStartEndProximityPenalty:g,futureConnectionLine:y,total:e+f+m+g+y,obstacleProximityRate:n,edgeProximityRate:s,futureConnectionStartEndProximityRate:o,futureConnectionLineRate:i}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?k(t,e):0,s=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},o=s.distFromStart+n,i=s.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,r=s.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=s.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=s.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let h=s.jumperPenalty,l=s.jumperPadFutureConnectionPenalty;t.isJumperExit&&(h+=this.jumperPenaltyDistance,l+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:o,weightedMmNearObstacle:i,weightedMmNearEdge:r,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:h,jumperPadFutureConnectionPenalty:l,total:o+i+r+a+c+h+l}}computeG(t){return this.computeGComponents(t).total}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o);s<e&&(e=s,n=o)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const s=k(t,n);if(s>this.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const o=s/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-o)**2}return e}getFutureConnectionLinePenalty(t){if(0===this.futureConnections.length)return 0;let e=1/0;const n=Math.min(1,(t.hComponents?.distanceToGoal??0)/this.FUTURE_CONNECTION_LINE_PROXIMITY)**2;for(const n of this.futureConnections){if(n.points.length<2)continue;const s=X(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,s)}if(e*=n,e<this.FUTURE_CONNECTION_LINE_PROXIMITY){const t=Math.max(.1,e/this.FUTURE_CONNECTION_LINE_PROXIMITY);return this.FUTURE_CONNECTION_LINE_PENALTY*(1-t)**2}return 0}getJumperPadFutureConnectionPenalty(t){if(!t.isJumperExit||!t.jumperEntry)return 0;const e=t.jumperEntry,n={x:t.x,y:t.y};let s=1/0;for(const t of this.futureConnections)for(const o of t.points){const t=k(e,o),i=k(n,o),r=Math.min(t,i);s=Math.min(s,r)}if(s<this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=s/this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;return this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY*(1-t)}return 0}getClearanceToObstacles(t){let e=1/0;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Df(n))e=Math.min(e,X(t,s.A,s.B));for(const s of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,s))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,s=e.end.y-e.start.y,o=Math.abs(n)>Math.abs(s),i=(o?Af:zf)/2,r=(o?zf:Af)/2;return Math.min(this.pointToRectDistance(t,e.start,i,r),this.pointToRectDistance(t,e.end,i,r))}pointToRectDistance(t,e,n,s){const o=Math.max(Math.abs(t.x-e.x)-n,0),i=Math.max(Math.abs(t.y-e.y)-s,0);return Math.hypot(o,i)}getClearanceToEdge(t){return Math.min(t.x-this.bounds.minX,this.bounds.maxX-t.x,t.y-this.bounds.minY,this.bounds.maxY-t.y)}getObstacleProximityPenalty(t){const e=this.getClearanceToObstacles(t),n=Math.max(0,e-(this.traceThickness+this.obstacleMargin)),s=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/s)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e>2*this.EDGE_PROX_SIGMA)return 0;const s=k(t,this.B),o=Math.min(1,s/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*o}getNodeKey(t){const e=t.isJumperExit?"_j":"";return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}${e}`}getJumperNeighbors(t){const e=[];if((t.gComponents?.distFromStart??0)<this.MIN_TRAVEL_BEFORE_JUMPER)return e;const n=[{dx:1,dy:0},{dx:-1,dy:0},{dx:0,dy:1},{dx:0,dy:-1}];for(const s of n){const n=2*Rf,o=t.x+s.dx*n,i=t.y+s.dy*n,r=this.findObstaclesBetween(t,{x:o,y:i});if(r.length>0)for(const n of r){const o=this.calculateJumperExit(t,n,s);o&&!this.exploredNodes.has(this.getNodeKey(o))&&(this.isNodeTooCloseToObstacle(o)||this.isNodeTooCloseToEdge(o)||!this.isJumperPlacementValid(t,o)||(o.gComponents=this.computeGComponents(o),o.hComponents=this.computeHComponents(o),o.g=o.gComponents.total,o.h=o.hComponents.total,o.f=this.computeF(o.g,o.h),e.push(o)))}}return e}calculateJumperExit(t,e,n){const s=Rf,o=Math.sqrt(n.dx*n.dx+n.dy*n.dy),i=n.dx/o,r=n.dy/o,a=t.x+i*s,c=t.y+r*s;return a<this.bounds.minX||a>this.bounds.maxX||c<this.bounds.minY||c>this.bounds.maxY?null:{x:a,y:c,z:0,parent:t,g:0,h:0,f:0,jumperEntry:{x:t.x,y:t.y},isJumperExit:!0,jumperCount:(t.jumperCount??0)+1}}isJumperTooCloseToTraces(t,e){const n=e.x-t.x,s=e.y-t.y,o=Math.abs(n)>Math.abs(s),i=(o?Af:zf)/2,r=(o?zf:Af)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-i,y:t.y-r},{x:t.x+i,y:t.y-r},{x:t.x-i,y:t.y+r},{x:t.x+i,y:t.y+r},{x:t.x-i,y:t.y},{x:t.x+i,y:t.y},{x:t.x,y:t.y-r},{x:t.x,y:t.y+r}];for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(s)continue;const o=Df(n);for(const n of o){for(const t of e)if(X(t,n.A,n.B)<this.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,i+a,r+a))return!0}}}return!1}isJumperPlacementValid(t,e){if(this.isJumperTooCloseToTraces(t,e))return!1;const n={route_type:"jumper",start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},footprint:"0603"};for(const t of this.existingJumpers)if(this.doJumpersOverlap(n,t))return!1;const s=this.getJumpersInPath(t);for(const t of s)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,s=Math.min(t.start.x,t.end.x)-Of/2-n,o=Math.max(t.start.x,t.end.x)+Of/2+n,i=Math.min(t.start.y,t.end.y)-Of/2-n,r=Math.max(t.start.y,t.end.y)+Of/2+n,a=Math.min(e.start.x,e.end.x)-Of/2-n,c=Math.max(e.start.x,e.end.x)+Of/2+n,h=Math.min(e.start.y,e.end.y)-Of/2-n,l=Math.max(e.start.y,e.end.y)+Of/2+n;return!(o<a||s>c||r<h||i>l)}getJumpersInPath(t){const e=[];let n=t;for(;n&&n.parent;)n.isJumperExit&&n.jumperEntry&&e.push({route_type:"jumper",start:n.jumperEntry,end:{x:n.x,y:n.y},footprint:"0603"}),n=n.parent;return e}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;if(!this.ALLOW_DIAGONAL&&0!==r&&0!==a)continue;const c=t.x+r*this.cellStep,h=t.y+a*this.cellStep,l=Ff(c,s,n),d=Ff(h,i,o),u={...t,parent:t,x:l,y:d,isJumperExit:!1,jumperEntry:void 0,jumperCount:t.jumperCount??0},p=this.getNodeKey(u);this.exploredNodes.has(p)||(this.isNodeTooCloseToObstacle(u)?(this.debug_nodesTooCloseToObstacle.add(p),this.exploredNodes.add(p)):this.isNodeTooCloseToEdge(u)?this.debug_nodesTooCloseToObstacle.add(p):this.doesPathToParentIntersectObstacle(u)?(this.debug_nodePathToParentIntersectsObstacle.add(p),this.exploredNodes.add(p)):(u.gComponents=this.computeGComponents(u),u.hComponents=this.computeHComponents(u),u.g=u.gComponents.total,u.h=u.hComponents.total,u.f=this.computeF(u.g,u.h),e.push(u)))}const r=this.getJumperNeighbors(t);return e.push(...r),e}getNodePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.parent;return e}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length;t++){const s=e[t];s.isJumperExit&&s.jumperEntry&&n.push({route_type:"jumper",start:s.jumperEntry,end:{x:s.x,y:s.y},footprint:"0603"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,traceThickness:this.traceThickness,route:e.map(t=>({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){const n=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*n/(1-n)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e),this.debug_exploredNodeValues.set(e,{g:t.g,h:t.h,f:t.f,gComponents:t.gComponents,hComponents:t.hComponents});const n=k(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n<=this.cellStep*Math.SQRT2&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}drawJumperPads(t,e,n,s,o){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Af,c=zf,h=Math.abs(i)>Math.abs(r),l=h?a:c,d=h?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*c,layer:s??"jumper-body",step:o})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++)t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:"rgba(255, 0, 0, 0.75)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`});for(const s of n.jumpers||[])this.drawJumperPads(t,s,"rgba(255, 0, 0, 0.5)",`obstacle-jumper-${e}`)}for(let e=0;e<this.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length<2)continue;const s=n.points[0],o=n.points[n.points.length-1];t.lines.push({points:[s,o],strokeColor:"rgba(0, 100, 255, 0.6)",strokeWidth:this.traceThickness,label:`Future: ${n.connectionName}`,layer:`future-connection-${e}`})}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e];if(this.debug_nodesTooCloseToObstacle.has(n))continue;if(this.debug_nodePathToParentIntersectsObstacle.has(n))continue;const[s,o]=n.split(",").map(Number),i=n.endsWith("_j"),r=this.debug_exploredNodeValues.get(n),a=r?.gComponents,c=r?.hComponents,h=c?.distanceToGoal??0,l=[i?"Explored (jumper)":"Explored"];l.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??"?"}`),l.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??"?"}`),l.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??"?"}`),l.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),l.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),l.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??"?"}`),l.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),l.push(`h.goalDist: ${h.toFixed(2)}`),l.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??"?"} (${h>0?((c?.obstacleProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??"?"} (${h>0?((c?.edgeProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${h>0?((c?.futureConnectionStartEndProximityPenalty??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??"?"} (${h>0?((c?.futureConnectionLine??0)/h).toFixed(3):0}/mm)`),l.push(`g: ${r?.g.toFixed(2)??"?"}`),l.push(`h: ${r?.h.toFixed(2)??"?"}`),l.push(`f: ${r?.f.toFixed(2)??"?"}`);const d=l.join("\n");t.rects.push({center:{x:s+this.initialNodeGridOffset.x,y:o+this.initialNodeGridOffset.y},fill:i?`rgba(0,255,255,${.4-e/this.debug_exploredNodesOrdered.length*.3})`:`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:d})}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x,y:e.y},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:"Next"})}const e=this.candidates.getTopN(5);for(let n=0;n<e.length;n++){const s=e[n],o=s.isJumperExit??!1,i=s.gComponents,r=s.hComponents,a=r?.distanceToGoal??0,c=[`Candidate #${n+1}${o?" (jumper)":""}`];c.push(`g.distFromStart: ${i?.distFromStart.toFixed(2)??"?"}`),c.push(`g.nearObstacle: ${i?.weightedMmNearObstacle.toFixed(2)??"?"}`),c.push(`g.nearEdge: ${i?.weightedMmNearEdge.toFixed(2)??"?"}`),c.push(`g.nearFutureConnPt: ${i?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),c.push(`g.nearFutureConnLine: ${i?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),c.push(`g.jumper: ${i?.jumperPenalty.toFixed(2)??"?"}`),c.push(`g.jumperPadFutureConn: ${i?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),c.push(`g: ${s.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${r?.obstacleProximity.toFixed(2)??"?"} (${a>0?((r?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${r?.edgeProximity.toFixed(2)??"?"} (${a>0?((r?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${r?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${a>0?((r?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${r?.futureConnectionLine.toFixed(2)??"?"} (${a>0?((r?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${s.h.toFixed(2)}`),c.push(`f: ${s.f.toFixed(2)}`);const h=c.join("\n");t.points.push({x:s.x,y:s.y,color:"gray",label:h})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route",strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,"rgba(0, 200, 0, 0.8)","solved-jumper")}const{minX:n,minY:s,maxX:o,maxY:i}=this.bounds;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};function Df(t){const e=[];for(let n=0;n<t.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const s=t.route[n],o=t.route[n+1],i=t.jumpers?.some(t=>{const e=Math.abs(t.start.x-s.x)<.001&&Math.abs(t.start.y-s.y)<.001&&Math.abs(t.end.x-o.x)<.001&&Math.abs(t.end.y-o.y)<.001,n=Math.abs(t.start.x-o.x)<.001&&Math.abs(t.start.y-o.y)<.001&&Math.abs(t.end.x-s.x)<.001&&Math.abs(t.end.y-s.y)<.001;return e||n});i||e.push({z:s.z,A:s,B:o})}return e}function Ff(t,e,n){return Math.max(e,Math.min(t,n))}var Yf=.8,Xf=.95,kf=class extends Ln{getSolverName(){return"IntraNodeSolverWithJumpers"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;traceWidth;activeSubSolver=null;lastActiveSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,rootConnectionName:n,x:o,y:i}of e.portPoints){const e=s.get(t);s.set(t,{rootConnectionName:e?.rootConnectionName??n,points:[...e?.points??[],{x:o,y:i,z:0}]})}this.unsolvedConnections=Array.from(s.entries().map(([t,{rootConnectionName:e,points:n}])=>({connectionName:t,rootConnectionName:e,points:n}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Vn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Vn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Gn(this.nodeWithPortPoints)}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:this.hyperParameters,connMap:this.connMap,traceWidth:this.traceWidth}}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o)return}const{connectionName:e,rootConnectionName:n,points:s}=t;this.activeSubSolver=new Lf({connectionName:e,rootConnectionName:n,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ne(this.nodeWithPortPoints),A:{x:s[0].x,y:s[0].y,z:0},B:{x:s[s.length-1].x,y:s[s.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=>(!n||t.rootConnectionName!==n)&&!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,s){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Yf,a=Xf,c=Math.abs(o)>Math.abs(i),h=c?r:a,l=c?a:r;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*a,layer:"jumper-body"})}visualize(){if(this.activeSubSolver&&!this.solved)return this.activeSubSolver.visualize();if(this.failed&&this.lastActiveSubSolver)return this.lastActiveSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,"layer: 0 (single-layer)"].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:Nn(s,.2),layer:"route-layer-0",strokeWidth:n.traceThickness})}for(const o of n.jumpers)this.drawJumperPads(t,o,Nn(s,.5),e)}}const e=Ne(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};export{wf as AssignableAutoroutingPipeline1Solver,Gd as AssignableAutoroutingPipeline2,ef as AssignableAutoroutingPipeline3,bd as AutoroutingPipeline1_OriginalUnravel,Tl as AutoroutingPipelineSolver,xf as AutoroutingPipelineSolver3_HgPortPointPathing,El as CapacityMeshSolver,Tu as CurvyIntraNodeSolver,Qp as HighDensitySolver,xe as InMemoryCache,kf as IntraNodeSolverWithJumpers,be as LocalStorageCache,Lf as SingleHighDensityRouteWithJumpersSolver,vh as calculateOptimalCapacityDepth,Rn as convertSrjToGraphicsObject,Se as getGlobalInMemoryCache,Pe as getGlobalLocalStorageCache,xh as getTunedTotalCapacity1,Me as setupGlobalCaches};
1
+ var t=Object.create,e=Object.defineProperty,n=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.getPrototypeOf,i=Object.prototype.hasOwnProperty,r=(t,e)=>function(){return e||(0,t[s(t)[0]])((e={exports:{}}).exports,e),e.exports},a=(r,a,c)=>(c=null!=r?t(o(r)):{},((t,o,r,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of s(o))i.call(t,c)||c===r||e(t,c,{get:()=>o[c],enumerable:!(a=n(o,c))||a.enumerable});return t})(!a&&r&&r.__esModule?c:e(c,"default",{value:r,enumerable:!0}),r)),c=r({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),h=r({"node_modules/kind-of/index.js"(t,e){var n=c(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),l=r({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),d=r({"node_modules/deep-rename-keys/index.js"(t,e){var n=h(),s=l();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),u=r({"node_modules/xml-reader/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),p=r({"node_modules/xml-lexer/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),f=r({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=p(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),m=r({"node_modules/xml-reader/dist/reader.js"(t,e){var n=u(),s=f(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}});function g(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function y(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}var{cos:x,sin:v,PI:b}=Math,{tan:P}=Math;a(d()),a(m());function S(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var M=(t,e)=>({...t,rects:[...t.rects??[],...e.rects??[]],points:[...t.points??[],...e.points??[]],lines:[...t.lines??[],...e.lines??[]],circles:[...t.circles??[],...e.circles??[]],arrows:[...t.arrows??[],...e.arrows??[]],texts:[...t.texts??[],...e.texts??[]]}),N=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function I(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var _=class extends N{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(S(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(S(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(S(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},C=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,e){let n=this.length++;for(;n>0;){const t=n-1>>1,s=this.values[t];if(e>=s)break;this.ids[n]=this.ids[t],this.values[n]=s,n=t}this.ids[n]=t,this.values[n]=e}pop(){if(0===this.length)return;const t=this.ids,e=this.values,n=t[0],s=--this.length;if(s>0){const n=t[s],o=e[s];let i=0;const r=s>>1;for(;i<r;){const n=1+(i<<1),r=n+1,a=n+(+(r<s)&+(e[r]<e[n]));if(e[a]>=o)break;t[i]=t[a],e[i]=e[a],i=a}t[i]=n,e[i]=o}return n}peek(){return this.length>0?this.ids[0]:void 0}peekValue(){return this.length>0?this.values[0]:void 0}shrink(){this.ids.length=this.values.length=this.length}},T=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],E=class t{static from(e,n=0){if(n%8!=0)throw new Error("byteOffset must be 8-byte aligned.");if(!e||void 0===e.byteLength||e.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[s,o]=new Uint8Array(e,n+0,2);if(251!==s)throw new Error("Data does not appear to be in a Flatbush format.");const i=o>>4;if(3!==i)throw new Error(`Got v${i} data when expected v3.`);const r=T[15&o];if(!r)throw new Error("Unrecognized array type.");const[a]=new Uint16Array(e,n+2,1),[c]=new Uint32Array(e,n+4,1);return new t(c,a,r,void 0,e,n)}constructor(t,e=16,n=Float64Array,s=ArrayBuffer,o,i=0){if(void 0===t)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=i;let r=t,a=r;this._levelBounds=[4*r];do{r=Math.ceil(r/this.nodeSize),a+=r,this._levelBounds.push(4*a)}while(1!==r);this.ArrayType=n,this.IndexArrayType=a<16384?Uint16Array:Uint32Array;const c=T.indexOf(n),h=4*a*n.BYTES_PER_ELEMENT;if(c<0)throw new Error(`Unexpected typed array class: ${n}.`);if(o)this.data=o,this._boxes=new n(o,i+8,4*a),this._indices=new this.IndexArrayType(o,i+8+h,a),this._pos=4*a,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1];else{const o=this.data=new s(8+h+a*this.IndexArrayType.BYTES_PER_ELEMENT);this._boxes=new n(o,8,4*a),this._indices=new this.IndexArrayType(o,8+h,a),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(o,0,2).set([251,48+c]),new Uint16Array(o,2,1)[0]=e,new Uint32Array(o,4,1)[0]=t}this._queue=new C}add(t,e,n=t,s=e){const o=this._pos>>2,i=this._boxes;return this._indices[o]=o,i[this._pos++]=t,i[this._pos++]=e,i[this._pos++]=n,i[this._pos++]=s,t<this.minX&&(this.minX=t),e<this.minY&&(this.minY=e),n>this.maxX&&(this.maxX=n),s>this.maxY&&(this.maxY=s),o}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);const t=this._boxes;if(this.numItems<=this.nodeSize)return t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,void(t[this._pos++]=this.maxY);const e=this.maxX-this.minX||1,n=this.maxY-this.minY||1,s=new Uint32Array(this.numItems);for(let o=0,i=0;o<this.numItems;o++){const r=t[i++],a=t[i++],c=t[i++],h=t[i++],l=Math.floor(65535*((r+c)/2-this.minX)/e),d=Math.floor(65535*((a+h)/2-this.minY)/n);s[o]=A(l,d)}R(s,t,this._indices,0,this.numItems-1,this.nodeSize);for(let e=0,n=0;e<this._levelBounds.length-1;e++){const s=this._levelBounds[e];for(;n<s;){const e=n;let o=t[n++],i=t[n++],r=t[n++],a=t[n++];for(let e=1;e<this.nodeSize&&n<s;e++)o=Math.min(o,t[n++]),i=Math.min(i,t[n++]),r=Math.max(r,t[n++]),a=Math.max(a,t[n++]);this._indices[this._pos>>2]=e,t[this._pos++]=o,t[this._pos++]=i,t[this._pos++]=r,t[this._pos++]=a}}}search(t,e,n,s,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=[],a=[];for(;void 0!==i;){const c=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let h=i;h<c;h+=4){const c=this._boxes[h];if(n<c)continue;const l=this._boxes[h+1];if(s<l)continue;const d=this._boxes[h+2];if(t>d)continue;const u=this._boxes[h+3];if(e>u)continue;const p=0|this._indices[h>>2];i>=4*this.numItems?r.push(p):(void 0===o||o(p,c,l,d,u))&&a.push(p)}i=r.pop()}return a}neighbors(t,e,n=1/0,s=1/0,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=this._queue,a=[],c=s*s;t:for(;void 0!==i;){const s=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let n=i;n<s;n+=4){const s=0|this._indices[n>>2],a=this._boxes[n],h=this._boxes[n+1],l=this._boxes[n+2],d=this._boxes[n+3],u=t<a?a-t:t>l?t-l:0,p=e<h?h-e:e>d?e-d:0,f=u*u+p*p;f>c||(i>=4*this.numItems?r.push(s<<1,f):(void 0===o||o(s))&&r.push(1+(s<<1),f))}for(;r.length&&1&r.peek();){if(r.peekValue()>c)break t;if(a.push(r.pop()>>1),a.length===n)break t}i=r.length?r.pop()>>1:void 0}return r.clear(),a}};function w(t,e){let n=0,s=e.length-1;for(;n<s;){const o=n+s>>1;e[o]>t?s=o:n=o+1}return e[n]}function R(t,e,n,s,o,i){if(Math.floor(s/i)>=Math.floor(o/i))return;const r=t[s],a=t[s+o>>1],c=t[o];let h=c;const l=Math.max(r,a);c>l?h=l:l===r?h=Math.max(a,c):l===a&&(h=Math.max(r,c));let d=s-1,u=o+1;for(;;){do{d++}while(t[d]<h);do{u--}while(t[u]>h);if(d>=u)break;O(t,e,n,d,u)}R(t,e,n,s,u,i),R(t,e,n,u+1,o,i)}function O(t,e,n,s,o){const i=t[s];t[s]=t[o],t[o]=i;const r=4*s,a=4*o,c=e[r],h=e[r+1],l=e[r+2],d=e[r+3];e[r]=e[a],e[r+1]=e[a+1],e[r+2]=e[a+2],e[r+3]=e[a+3],e[a]=c,e[a+1]=h,e[a+2]=l,e[a+3]=d;const u=n[s];n[s]=n[o],n[o]=u}function A(t,e){let n=t^e,s=65535^n,o=65535^(t|e),i=t&(65535^e),r=n|s>>1,a=n>>1^n,c=o>>1^s&i>>1^o,h=n&o>>1^i>>1^i;n=r,s=a,o=c,i=h,r=n&n>>2^s&s>>2,a=n&s>>2^s&(n^s)>>2,c^=n&o>>2^s&i>>2,h^=s&o>>2^(n^s)&i>>2,n=r,s=a,o=c,i=h,r=n&n>>4^s&s>>4,a=n&s>>4^s&(n^s)>>4,c^=n&o>>4^s&i>>4,h^=s&o>>4^(n^s)&i>>4,n=r,s=a,o=c,i=h,c^=n&o>>8^s&i>>8,h^=s&o>>8^(n^s)&i>>8,n=c^c>>1,s=h^h>>1;let l=t^e,d=s|65535^(l|n);return l=16711935&(l|l<<8),l=252645135&(l|l<<4),l=858993459&(l|l<<2),l=1431655765&(l|l<<1),d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),(d<<1|l)>>>0}function z(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}function D(t,e,n){return Math.max(e,Math.min(n,t))}function L(t,e,n,s){const o=F(t,e,n),i=F(t,e,s),r=F(n,s,t),a=F(n,s,e);return o!==i&&r!==a||(!(0!==o||!Y(t,n,e))||(!(0!==i||!Y(t,s,e))||(!(0!==r||!Y(n,t,s))||!(0!==a||!Y(n,e,s)))))}function F(t,e,n){const s=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===s?0:s>0?1:2}function Y(t,e,n){return e.x<=Math.max(t.x,n.x)&&e.x>=Math.min(t.x,n.x)&&e.y<=Math.max(t.y,n.y)&&e.y>=Math.min(t.y,n.y)}function X(t,e,n){const s=(n.x-e.x)**2+(n.y-e.y)**2;if(0===s)return k(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return k(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function k(t,e){const n=t.x-e.x,s=t.y-e.y;return Math.sqrt(n*n+s*s)}function $(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=t.x-n.x,h=t.y-n.y,l=o*a-i*r;if(Math.abs(l)<1e-10)return null;const d=(h*r-c*a)/l,u=(o*h-i*c)/l,p=1e-9;if(d>=-1e-9&&d<=1+p&&u>=-1e-9&&u<=1+p){return{x:t.x+d*o,y:t.y+d*i}}return null}function B(t,e){const n=e.width/2,s=e.height/2,o=e.center.x-n,i=e.center.x+n,r=e.center.y-s,a=e.center.y+s;if(t.x>=o&&t.x<=i&&t.y>=r&&t.y<=a)return 0;return k(t,{x:D(t.x,o,i),y:D(t.y,r,a)})}function j(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var W=t=>{if("minX"in t)return t;const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,minY:t.center.y-n,maxX:t.center.x+e,maxY:t.center.y+n}},H=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],U=t=>{const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];e.push([s,o])}return e},V=(t,e,n)=>{const s=(t.y-e.y)*(n.x-e.x)-(t.x-e.x)*(n.y-e.y);if(Math.abs(s)>1e-9)return!1;const o=(t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y);if(o<0)return!1;return!(o>(n.x-e.x)**2+(n.y-e.y)**2)},G=(t,e)=>{if(e.length<3)return!1;const n=U(e);for(const[e,s]of n)if(V(t,e,s))return!0;let s=!1;for(let n=0,o=e.length-1;n<e.length;o=n++){const i=e[n].x,r=e[n].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(s=!s)}return s},Z=(t,e)=>{const n=H(t),s=[[n[0],n[1]],[n[1],n[2]],[n[2],n[3]],[n[3],n[0]]],o=U(e);for(const[t,e]of o)for(const[n,o]of s)if(L(t,e,n,o))return!0;return!1},q=(t,e)=>((t,e)=>!(e.length<3)&&(!!e.some(e=>((t,e)=>t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY)(e,t))||(!!H(t).some(t=>G(t,e))||Z(t,e))))(W(t),e),J=(t,e)=>((t,e)=>!(e.length<3)&&(!!H(t).every(t=>G(t,e))&&!Z(t,e)))(W(t),e);function K(t,e,n,s){if(t.x===e.x&&t.y===e.y)return X(t,n,s);if(n.x===s.x&&n.y===s.y)return X(n,t,e);if(L(t,e,n,s))return 0;const o=[X(t,n,s),X(e,n,s),X(n,t,e),X(s,t,e)];return Math.min(...o)}function Q(t,e,n){const s=n.width/2,o=n.height/2;return function(t,e,n){const s={x:n.minX,y:n.minY},o={x:n.maxX,y:n.minY},i={x:n.minX,y:n.maxY},r={x:n.maxX,y:n.maxY};if(L(t,e,s,o)||L(t,e,o,r)||L(t,e,r,i)||L(t,e,i,s))return 0;if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY&&e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;const a=[X(s,t,e),X(o,t,e),X(i,t,e),X(r,t,e)];if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY)return 0;if(e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;if(t.x<n.minX||t.x>n.maxX||t.y<n.minY||t.y>n.maxY){const e=D(t.x,n.minX,n.maxX),s=D(t.y,n.minY,n.maxY);a.push(k(t,{x:e,y:s}))}if(e.x<n.minX||e.x>n.maxX||e.y<n.minY||e.y>n.maxY){const t=D(e.x,n.minX,n.maxX),s=D(e.y,n.minY,n.maxY);a.push(k(e,{x:t,y:s}))}return Math.min(...a)}(t,e,{minX:n.center.x-s,maxX:n.center.x+s,minY:n.center.y-o,maxY:n.center.y+o})}function tt(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(0===i)return{x:e.x,y:e.y};let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;r=Math.max(0,Math.min(1,r));return{x:e.x+r*s,y:e.y+r*o}}function et(t,e,n=0,s=t.length-1,o=st){for(;s>n;){if(s-n>600){const i=s-n+1,r=e-n+1,a=Math.log(i),c=.5*Math.exp(2*a/3),h=.5*Math.sqrt(a*c*(i-c)/i)*(r-i/2<0?-1:1);et(t,e,Math.max(n,Math.floor(e-r*c/i+h)),Math.min(s,Math.floor(e+(i-r)*c/i+h)),o)}const i=t[e];let r=n,a=s;for(nt(t,n,e),o(t[s],i)>0&&nt(t,n,s);r<a;){for(nt(t,r,a),r++,a--;o(t[r],i)<0;)r++;for(;o(t[a],i)>0;)a--}0===o(t[n],i)?nt(t,n,a):(a++,nt(t,a,s)),a<=e&&(n=a+1),e<=a&&(s=a-1)}}function nt(t,e,n){const s=t[e];t[e]=t[n],t[n]=s}function st(t,e){return t<e?-1:t>e?1:0}var ot=class{constructor(t=9){this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}all(){return this._all(this.data,[])}search(t){let e=this.data;const n=[];if(!gt(t,e))return n;const s=this.toBBox,o=[];for(;e;){for(let i=0;i<e.children.length;i++){const r=e.children[i],a=e.leaf?s(r):r;gt(t,a)&&(e.leaf?n.push(r):mt(t,a)?this._all(r,n):o.push(r))}e=o.pop()}return n}collides(t){let e=this.data;if(!gt(t,e))return!1;const n=[];for(;e;){for(let s=0;s<e.children.length;s++){const o=e.children[s],i=e.leaf?this.toBBox(o):o;if(gt(t,i)){if(e.leaf||mt(t,i))return!0;n.push(o)}}e=n.pop()}return!1}load(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(let e=0;e<t.length;e++)this.insert(t[e]);return this}let e=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===e.height)this._splitRoot(this.data,e);else{if(this.data.height<e.height){const t=this.data;this.data=e,e=t}this._insert(e,this.data.height-e.height-1,!0)}else this.data=e;return this}insert(t){return t&&this._insert(t,this.data.height-1),this}clear(){return this.data=yt([]),this}remove(t,e){if(!t)return this;let n=this.data;const s=this.toBBox(t),o=[],i=[];let r,a,c;for(;n||o.length;){if(n||(n=o.pop(),a=o[o.length-1],r=i.pop(),c=!0),n.leaf){const s=it(t,n.children,e);if(-1!==s)return n.children.splice(s,1),o.push(n),this._condense(o),this}c||n.leaf||!mt(n,s)?a?(r++,n=a.children[r],c=!1):n=null:(o.push(n),i.push(r),r=0,a=n,n=n.children[0])}return this}toBBox(t){return t}compareMinX(t,e){return t.minX-e.minX}compareMinY(t,e){return t.minY-e.minY}toJSON(){return this.data}fromJSON(t){return this.data=t,this}_all(t,e){const n=[];for(;t;)t.leaf?e.push(...t.children):n.push(...t.children),t=n.pop();return e}_build(t,e,n,s){const o=n-e+1;let i,r=this._maxEntries;if(o<=r)return i=yt(t.slice(e,n+1)),rt(i,this.toBBox),i;s||(s=Math.ceil(Math.log(o)/Math.log(r)),r=Math.ceil(o/Math.pow(r,s-1))),i=yt([]),i.leaf=!1,i.height=s;const a=Math.ceil(o/r),c=a*Math.ceil(Math.sqrt(r));xt(t,e,n,c,this.compareMinX);for(let o=e;o<=n;o+=c){const e=Math.min(o+c-1,n);xt(t,o,e,a,this.compareMinY);for(let n=o;n<=e;n+=a){const o=Math.min(n+a-1,e);i.children.push(this._build(t,n,o,s-1))}}return rt(i,this.toBBox),i}_chooseSubtree(t,e,n,s){for(;s.push(e),!e.leaf&&s.length-1!==n;){let n,s=1/0,o=1/0;for(let i=0;i<e.children.length;i++){const r=e.children[i],a=dt(r),c=pt(t,r)-a;c<o?(o=c,s=a<s?a:s,n=r):c===o&&a<s&&(s=a,n=r)}e=n||e.children[0]}return e}_insert(t,e,n){const s=n?t:this.toBBox(t),o=[],i=this._chooseSubtree(s,this.data,e,o);for(i.children.push(t),ct(i,s);e>=0&&o[e].children.length>this._maxEntries;)this._split(o,e),e--;this._adjustParentBBoxes(s,o,e)}_split(t,e){const n=t[e],s=n.children.length,o=this._minEntries;this._chooseSplitAxis(n,o,s);const i=this._chooseSplitIndex(n,o,s),r=yt(n.children.splice(i,n.children.length-i));r.height=n.height,r.leaf=n.leaf,rt(n,this.toBBox),rt(r,this.toBBox),e?t[e-1].children.push(r):this._splitRoot(n,r)}_splitRoot(t,e){this.data=yt([t,e]),this.data.height=t.height+1,this.data.leaf=!1,rt(this.data,this.toBBox)}_chooseSplitIndex(t,e,n){let s,o=1/0,i=1/0;for(let r=e;r<=n-e;r++){const e=at(t,0,r,this.toBBox),a=at(t,r,n,this.toBBox),c=ft(e,a),h=dt(e)+dt(a);c<o?(o=c,s=r,i=h<i?h:i):c===o&&h<i&&(i=h,s=r)}return s||n-e}_chooseSplitAxis(t,e,n){const s=t.leaf?this.compareMinX:ht,o=t.leaf?this.compareMinY:lt;this._allDistMargin(t,e,n,s)<this._allDistMargin(t,e,n,o)&&t.children.sort(s)}_allDistMargin(t,e,n,s){t.children.sort(s);const o=this.toBBox,i=at(t,0,e,o),r=at(t,n-e,n,o);let a=ut(i)+ut(r);for(let s=e;s<n-e;s++){const e=t.children[s];ct(i,t.leaf?o(e):e),a+=ut(i)}for(let s=n-e-1;s>=e;s--){const e=t.children[s];ct(r,t.leaf?o(e):e),a+=ut(r)}return a}_adjustParentBBoxes(t,e,n){for(let s=n;s>=0;s--)ct(e[s],t)}_condense(t){for(let e,n=t.length-1;n>=0;n--)0===t[n].children.length?n>0?(e=t[n-1].children,e.splice(e.indexOf(t[n]),1)):this.clear():rt(t[n],this.toBBox)}};function it(t,e,n){if(!n)return e.indexOf(t);for(let s=0;s<e.length;s++)if(n(t,e[s]))return s;return-1}function rt(t,e){at(t,0,t.children.length,e,t)}function at(t,e,n,s,o){o||(o=yt(null)),o.minX=1/0,o.minY=1/0,o.maxX=-1/0,o.maxY=-1/0;for(let i=e;i<n;i++){const e=t.children[i];ct(o,t.leaf?s(e):e)}return o}function ct(t,e){return t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),t}function ht(t,e){return t.minX-e.minX}function lt(t,e){return t.minY-e.minY}function dt(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function ut(t){return t.maxX-t.minX+(t.maxY-t.minY)}function pt(t,e){return(Math.max(e.maxX,t.maxX)-Math.min(e.minX,t.minX))*(Math.max(e.maxY,t.maxY)-Math.min(e.minY,t.minY))}function ft(t,e){const n=Math.max(t.minX,e.minX),s=Math.max(t.minY,e.minY),o=Math.min(t.maxX,e.maxX),i=Math.min(t.maxY,e.maxY);return Math.max(0,o-n)*Math.max(0,i-s)}function mt(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function gt(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function yt(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function xt(t,e,n,s,o){const i=[e,n];for(;i.length;){if((n=i.pop())-(e=i.pop())<=s)continue;const r=e+Math.ceil((n-e)/s/2)*s;et(t,r,e,n,o),i.push(e,r,r,n)}}var vt=1e-4;var bt=[{facingDirection:"x-",dx:-1,dy:0,startX:-.5,startY:.5,endX:-.5,endY:-.5},{facingDirection:"x+",dx:1,dy:0,startX:.5,startY:.5,endX:.5,endY:-.5},{facingDirection:"y-",dx:0,dy:-1,startX:-.5,startY:-.5,endX:.5,endY:-.5},{facingDirection:"y+",dx:0,dy:1,startX:.5,startY:.5,endX:-.5,endY:.5}],Pt={"x-":bt.find(t=>"x-"===t.facingDirection),"x+":bt.find(t=>"x+"===t.facingDirection),"y-":bt.find(t=>"y-"===t.facingDirection),"y+":bt.find(t=>"y+"===t.facingDirection)},St={"x-":{x:-1,y:0},"x+":{x:1,y:0},"y-":{x:0,y:-1},"y+":{x:0,y:1}},Mt=(t,e)=>{const{dir:n,amt:s}=e,o=St[n];return t.map(t=>({x:t.x+o.x*s,y:t.y+o.y*s}))},Nt=1e-4,It=class extends N{constructor(t){super(),this.input=t;for(const t of this.input.meshNodes)for(const e of bt){let n={x:t.center.x+t.width*e.startX,y:t.center.y+t.height*e.startY},s={x:t.center.x+t.width*e.endX,y:t.center.y+t.height*e.endY};n.x>s.x&&([n,s]=[s,n]),Math.abs(n.x-s.x)<Nt&&n.y>s.y&&([n,s]=[s,n]);for(const o of t.availableZ)this.unprocessedEdges.push({parent:t,start:n,end:s,facingDirection:e.facingDirection,z:o})}this.allEdges=[...this.unprocessedEdges],this.edgeSpatialIndex=new E(this.allEdges.length);for(const t of this.allEdges)this.edgeSpatialIndex.add(t.start.x,t.start.y,t.end.x,t.end.y);this.edgeSpatialIndex.finish()}allEdges;unprocessedEdges=[];segmentsWithAdjacentEmptySpace=[];edgeSpatialIndex;lastCandidateEdge=null;lastOverlappingEdges=null;lastUncoveredSegments=null;_step(){if(0===this.unprocessedEdges.length)return this.solved=!0,this.lastCandidateEdge=null,this.lastOverlappingEdges=null,void(this.lastUncoveredSegments=null);const t=this.unprocessedEdges.shift();this.lastCandidateEdge=t;const e=this.edgeSpatialIndex.search(t.start.x-Nt,t.start.y-Nt,t.end.x+Nt,t.end.y+Nt).map(t=>this.allEdges[t]).filter(e=>e.z===t.z);this.lastOverlappingEdges=e;const n=function(t,e){const n=Math.abs(t.start.y-t.end.y)<vt,s=Math.abs(t.start.x-t.end.x)<vt;if(!n&&!s)return[];const o=n?"x":"y",i=n?"y":"x",r=t.start[i],a=t.start[o],c=t.end[o],h=Math.min(a,c),l=Math.max(a,c),d=t=>Math.max(h,Math.min(l,t)),u=[];for(const n of e){if(n===t)continue;const e=Math.abs(n.start.y-n.end.y)<vt,s=Math.abs(n.start.x-n.end.x)<vt;if("x"===o&&!e)continue;if("y"===o&&!s)continue;if(Math.abs(n.start[i]-r)>vt)continue;const a=Math.min(n.start[o],n.end[o]),c=Math.max(n.start[o],n.end[o]),h=d(a),l=d(c);l-h>vt&&u.push({s:h,e:l})}if(0===u.length)return[{...t,start:{...t.start},end:{...t.end}}];u.sort((t,e)=>t.s-e.s);const p=[];for(const t of u){const e=p[p.length-1];!e||t.s>e.e+vt?p.push({...t}):e.e=Math.max(e.e,t.e)}const f=[];let m=h;for(const t of p)if(t.s>m+vt&&f.push({s:m,e:t.s}),m=Math.max(m,t.e),m>=l-vt)break;return l>m+vt&&f.push({s:m,e:l}),0===f.length?[]:f.filter(t=>t.e-t.s>vt).map(e=>{const n="x"===o?{x:e.s,y:r}:{x:r,y:e.s},s="x"===o?{x:e.e,y:r}:{x:r,y:e.e};return{parent:t.parent,facingDirection:t.facingDirection,start:n,end:s,z:t.z}})}(t,e);this.lastUncoveredSegments=n,this.segmentsWithAdjacentEmptySpace.push(...n)}getOutput(){return{segmentsWithAdjacentEmptySpace:this.segmentsWithAdjacentEmptySpace}}visualize(){const t={title:"FindSegmentsWithAdjacentEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)"});for(const e of this.unprocessedEdges)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:-.1}),strokeColor:"rgba(0, 0, 255, 0.5)",strokeDash:"5 5"});for(const e of this.segmentsWithAdjacentEmptySpace)t.lines.push({points:[e.start,e.end],strokeColor:"rgba(0,255,0, 0.5)"});if(this.lastCandidateEdge&&t.lines.push({points:[this.lastCandidateEdge.start,this.lastCandidateEdge.end],strokeColor:"blue"}),this.lastOverlappingEdges)for(const e of this.lastOverlappingEdges)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:.05}),strokeColor:"red",strokeDash:"2 2"});if(this.lastUncoveredSegments)for(const e of this.lastUncoveredSegments)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:-.05}),strokeColor:"green",strokeDash:"2 2"});return t}},_t=t=>({minX:Math.min(...t.map(t=>t.x)),minY:Math.min(...t.map(t=>t.y)),maxX:Math.max(...t.map(t=>t.x)),maxY:Math.max(...t.map(t=>t.y))}),Ct=1e-4,Tt=class extends N{constructor(t){super(),this.input=t,this.unprocessedSegments=[...this.input.segmentsWithAdjacentEmptySpace],this.rectSpatialIndex=new ot,this.rectSpatialIndex.load(this.input.boardVoid?.boardVoidRects.map((t,e)=>({capacityMeshNodeId:`void-rect-${e}`,center:{x:t.x+t.width/2,y:t.y+t.height/2},width:t.width,height:t.height,availableZ:Array.from({length:this.input.boardVoid?.layerCount||0},(t,e)=>e),layer:"void",minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))||[]),this.rectSpatialIndex.load(this.input.inputMeshNodes.map(t=>({...t,minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2})))}unprocessedSegments=[];expandedSegments=[];lastSegment=null;lastSearchBounds=null;lastCollidingNodes=null;lastSearchCorner1=null;lastSearchCorner2=null;lastExpandedSegment=null;rectSpatialIndex;_step(){if(0===this.unprocessedSegments.length)return void(this.solved=!0);const t=this.unprocessedSegments.shift();this.lastSegment=t;const{dx:e,dy:n}=Pt[t.facingDirection],s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=Math.sqrt(s**2+o**2),r=s/i,a=o/i;let c=null,h=1;const l={x:t.start.x+e*Ct+r*Ct*10,y:t.start.y+n*Ct+a*Ct*10},d={x:t.end.x+e*Ct-r*Ct*10,y:t.end.y+n*Ct-a*Ct*10};for(this.lastSearchCorner1=l,this.lastSearchCorner2=d;(!c||0===c.length)&&h<1e3;){const s=_t([l,d,{x:l.x+e*h,y:l.y+n*h},{x:d.x+e*h,y:d.y+n*h}]);this.lastSearchBounds=s,c=this.rectSpatialIndex.search(s).filter(e=>e.availableZ.includes(t.z)).filter(e=>e.capacityMeshNodeId!==t.parent.capacityMeshNodeId),h*=4}if(!c||0===c.length)return;this.lastCollidingNodes=c;let u=1/0;for(const e of c){const n=Q(t.start,t.end,e);n<u&&(u=n)}const p=u,f=_t([t.start,t.end,{x:t.start.x+e*p,y:t.start.y+n*p},{x:t.end.x+e*p,y:t.end.y+n*p}]),m={x:(f.minX+f.maxX)/2,y:(f.minY+f.maxY)/2},g=f.maxX-f.minX,y=f.maxY-f.minY,x={segment:t,newNode:{capacityMeshNodeId:`new-${t.parent.capacityMeshNodeId}-${this.expandedSegments.length}`,center:m,width:g,height:y,availableZ:[t.z],layer:t.parent.layer}};this.lastExpandedSegment=x,g<Ct||y<Ct||(this.expandedSegments.push(x),this.rectSpatialIndex.insert({...x.newNode,...f}))}getOutput(){return{expandedSegments:this.expandedSegments}}visualize(){const t={title:"ExpandEdgesToEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.inputMeshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});for(const{newNode:e}of this.expandedSegments)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"green",label:`expandedSegment (z=${e.availableZ.join(",")})`,layer:`z${e.availableZ.join(",")}`});if(this.lastSegment&&t.lines.push({points:[this.lastSegment.start,this.lastSegment.end],strokeColor:"rgba(0, 0, 255, 0.5)"}),this.lastSearchBounds&&t.rects.push({center:{x:(this.lastSearchBounds.minX+this.lastSearchBounds.maxX)/2,y:(this.lastSearchBounds.minY+this.lastSearchBounds.maxY)/2},width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:"rgba(0, 0, 255, 0.25)"}),this.lastSearchCorner1&&this.lastSearchCorner2&&(t.points.push({x:this.lastSearchCorner1.x,y:this.lastSearchCorner1.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner1",`z=${this.lastSegment?.z}`].join("\n")}),t.points.push({x:this.lastSearchCorner2.x,y:this.lastSearchCorner2.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner2",`z=${this.lastSegment?.z}`].join("\n")})),this.lastExpandedSegment&&t.rects.push({center:this.lastExpandedSegment.newNode.center,width:this.lastExpandedSegment.newNode.width,height:this.lastExpandedSegment.newNode.height,fill:"purple",label:`expandedSegment (z=${this.lastExpandedSegment.segment.z})`}),this.lastCollidingNodes)for(const e of this.lastCollidingNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255, 0, 0, 0.5)"});return t}},Et=class extends _{findSegmentsWithAdjacentEmptySpaceSolver;expandEdgesToEmptySpaceSolver;pipelineDef=[I("findSegmentsWithAdjacentEmptySpaceSolver",It,t=>[{meshNodes:t.inputProblem.meshNodes}],{onSolved:()=>{}}),I("expandEdgesToEmptySpaceSolver",Tt,t=>[{inputMeshNodes:t.inputProblem.meshNodes,segmentsWithAdjacentEmptySpace:t.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace,boardVoid:t.inputProblem.boardVoid}],{onSolved:()=>{}})];getOutput(){const t=(this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[]).map(t=>t.newNode);return{outputNodes:[...this.inputProblem.meshNodes,...t]}}initialVisualize(){const t={title:"GapFillSolverPipeline - Initial",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.inputProblem.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t={title:"GapFillSolverPipeline - Final",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]},{outputNodes:e}=this.getOutput(),n=this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[],s=new Set(n.map(t=>t.newNode.capacityMeshNodeId));for(const n of e){const e=s.has(n.capacityMeshNodeId);t.rects.push({center:n.center,width:n.width,height:n.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")})}return t}},wt=1e-9,Rt=(t,e,n)=>Math.max(e,Math.min(n,t)),Ot=(t,e)=>t>e+wt,At=(t,e)=>t>e-wt,zt=(t,e)=>t<e-wt,Dt=(t,e)=>t<e+wt;function Lt(t,e){return!(t.x+t.width<=e.x+wt||e.x+e.width<=t.x+wt||t.y+t.height<=e.y+wt||e.y+e.height<=t.y+wt)}function Ft(t,e){const n=[[e.x,e.y,e.x+e.width,e.y],[e.x+e.width,e.y,e.x+e.width,e.y+e.height],[e.x+e.width,e.y+e.height,e.x,e.y+e.height],[e.x,e.y+e.height,e.x,e.y]];let s=1/0;for(const[e,o,i,r]of n){const n=t.x-e,a=t.y-o,c=i-e,h=r-o,l=c*c+h*h;let d=0!==l?(n*c+a*h)/l:0;d=Rt(d,0,1);const u=e+d*c,p=o+d*h;s=Math.min(s,Math.hypot(t.x-u,t.y-p))}return s}function Yt(t,e){const n=Math.max(t[0],e[0]),s=Math.min(t[1],e[1]);return s>n+wt?[n,s]:null}function Xt(t,e){if(!Lt(t,e))return[t];const n=Yt([t.x,t.x+t.width],[e.x,e.x+e.width]),s=Yt([t.y,t.y+t.height],[e.y,e.y+e.height]);if(!n||!s)return[t];const[o,i]=n,[r,a]=s,c=[];o>t.x+wt&&c.push({x:t.x,y:t.y,width:o-t.x,height:t.height}),t.x+t.width>i+wt&&c.push({x:i,y:t.y,width:t.x+t.width-i,height:t.height});const h=Math.max(0,i-o);return h>wt&&r>t.y+wt&&c.push({x:o,y:t.y,width:h,height:r-t.y}),h>wt&&t.y+t.height>a+wt&&c.push({x:o,y:a,width:h,height:t.y+t.height-a}),c.filter(t=>t.width>wt&&t.height>wt)}function kt(t,e){let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s].x,r=e[s].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(n=!n)}return n}function $t(t,e){if(!e||e.length<3)return[];const n=e.length>100?function(t,e){const n=t=>Math.round(t/e)*e,s=new Set,o=[];for(const e of t){const t=n(e.x),i=n(e.y),r=`${t},${i}`;s.has(r)||(s.add(r),o.push({x:t,y:i}))}return o}(e,Math.max(t.width,t.height)/100):e,s=new Set([t.x,t.x+t.width]),o=new Set([t.y,t.y+t.height]);for(const t of n)s.add(t.x),o.add(t.y);const i=Array.from(s).sort((t,e)=>t-e),r=Array.from(o).sort((t,e)=>t-e),a=[];for(let n=0;n<i.length-1;n++)for(let s=0;s<r.length-1;s++){const o=i[n],c=i[n+1],h=r[s],l=r[s+1],d=(o+c)/2,u=(h+l)/2;d>=t.x&&d<=t.x+t.width&&u>=t.y&&u<=t.y+t.height&&(kt({x:d,y:u},e)||a.push({x:o,y:h,width:c-o,height:l-h}))}const c=[];a.sort((t,e)=>Math.abs(t.y-e.y)>wt?t.y-e.y:t.x-e.x);let h=null;for(const t of a){if(!h){h=t;continue}const e=Math.abs(h.y-t.y)<wt,n=Math.abs(h.height-t.height)<wt,s=Math.abs(h.x+h.width-t.x)<wt;e&&n&&s?h.width+=t.width:(c.push(h),h=t)}h&&c.push(h),c.sort((t,e)=>Math.abs(t.x-e.x)>wt?t.x-e.x:t.y-e.y);const l=[];h=null;for(const t of c){if(!h){h=t;continue}const e=Math.abs(h.x-t.x)<wt,n=Math.abs(h.width-t.width)<wt,s=Math.abs(h.y+h.height-t.y)<wt;e&&n&&s?h.height+=t.height:(l.push(h),h=t)}return h&&l.push(h),l}function Bt(t){const e=t.toLowerCase();if("top"===e)return-1e6;if("bottom"===e)return 1e6;const n=/^inner(\d+)$/i.exec(e);return n?parseInt(n[1],10)||0:100+e.charCodeAt(0)}function jt(t){const e=function(t){return Array.from(new Set(t)).sort((t,e)=>{const n=Bt(t),s=Bt(e);return n!==s?n-s:t.localeCompare(e)})}((t.obstacles??[]).flatMap(t=>t.layers??[])),n=Math.max(1,t.layerCount||e.length||1),s=Array.from({length:n},(t,e)=>0===e?"top":e===n-1?"bottom":`inner${e}`),o=[],i=new Set,r=t=>{const e=t.toLowerCase();i.has(e)||(i.add(e),o.push(t))};s.forEach(r),e.forEach(r);const a=o.slice(0,n),c=new Map;return a.forEach((t,e)=>c.set(t.toLowerCase(),e)),o.slice(a.length).forEach(t=>{const e=t.toLowerCase();c.set(e,(t=>{if(a.length<=1)return 0;if("top"===t)return 0;if("bottom"===t)return a.length-1;const e=/^inner(\d+)$/i.exec(t);if(e){if(a.length<=2)return a.length-1;const t=parseInt(e[1],10),n=a.length-2;return Math.min(n,Math.max(1,Number.isFinite(t)?t:1))}return 0})(e))}),{layerNames:a,zIndexByName:c}}function Wt(t,e){if(t.zLayers?.length)return Array.from(new Set(t.zLayers)).sort((t,e)=>t-e);const n=(t.layers??[]).map(t=>e.get(t.toLowerCase())).filter(t=>"number"==typeof t);return Array.from(new Set(n)).sort((t,e)=>t-e)}function Ht(t){const e=t.width,n=t.height;return"number"!=typeof e||"number"!=typeof n?null:{x:t.center.x-e/2,y:t.center.y-n/2,width:e,height:n}}var Ut=1e-9,Vt=t=>Math.abs(t.rect.x+t.rect.width/2-t.startX)<Ut&&Math.abs(t.rect.y+t.rect.height/2-t.startY)<Ut&&Math.abs(t.rect.width-t.initialW)<Ut&&Math.abs(t.rect.height-t.initialH)<Ut,Gt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:e.x+e.width-t.x,height:t.height}),Zt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:t.width,height:e.y+e.height-t.y}),qt=({rect:t,bounds:e})=>({x:e.x,y:t.y,width:t.x-e.x,height:t.height}),Jt=({rect:t,bounds:e})=>({x:t.x,y:e.y,width:t.width,height:t.y-e.y});function Kt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x+n.width-e.x;for(const t of s){if(e.y+e.height>t.y+wt&&t.y+t.height>e.y+wt)if(At(t.x,e.x+e.width))i=Math.min(i,t.x-e.x);else if(t.x+t.width>e.x+e.width-wt&&t.x<e.x+e.width+wt)return 0}let r=Math.max(0,i-e.width);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function Qt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y+n.height-e.y;for(const t of s){if(e.x+e.width>t.x+wt&&t.x+t.width>e.x+wt)if(At(t.y,e.y+e.height))i=Math.min(i,t.y-e.y);else if(t.y+t.height>e.y+e.height-wt&&t.y<e.y+e.height+wt)return 0}let r=Math.max(0,i-e.height);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}function te(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x;for(const t of s){if(e.y+e.height>t.y+wt&&t.y+t.height>e.y+wt)if(Dt(t.x+t.width,e.x))i=Math.max(i,t.x+t.width);else if(t.x<e.x+wt&&t.x+t.width>e.x-wt)return 0}let r=Math.max(0,e.x-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function ee(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y;for(const t of s){if(e.x+e.width>t.x+wt&&t.x+t.width>e.x+wt)if(Dt(t.y+t.height,e.y))i=Math.max(i,t.y+t.height);else if(t.y<e.y+wt&&t.y+t.height>e.y-wt)return 0}let r=Math.max(0,e.y-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}var ne=t=>({x:t.minX,y:t.minY,width:t.maxX-t.minX,height:t.maxY-t.minY}),se=t=>{const{rect:e,seen:n,blockers:s}=t,o=`${e.x}|${e.y}|${e.width}|${e.height}`;n.has(o)||(n.add(o),s.push(e))};function oe(t){const{startX:e,startY:n,gridSize:s,bounds:o,obsticalIndexByLayer:i,placedIndexByLayer:r,initialCellRatio:a,maxAspectRatio:c,minReq:h}=t,l=Math.max(1e-9,s*a),d=Math.max(l,h.width),u=Math.max(l,h.height),p=[],f=new Set,m=r.length,g=s=>{const a=(t=>{const{bounds:e,rect:n}=t,s=Math.max(e.x,n.x),o=Math.max(e.y,n.y),i=Math.min(e.x+e.width,n.x+n.width),r=Math.min(e.y+e.height,n.y+n.height);return i<=s+wt||r<=o+wt?null:{minX:s,minY:o,maxX:i,maxY:r}})({bounds:o,rect:s});if(a)for(const s of t.zLayers){const t=i[s];if(t)for(const e of t.search(a))se({rect:ne(e),seen:f,blockers:p});const o=r[s];if(o)for(const t of o.search(a)){if(!(t.zLayers.length>=m))continue;const s=ne(t);Vt({rect:s,startX:e,startY:n,initialW:d,initialH:u})||se({rect:s,seen:f,blockers:p})}}},y=[{ox:0,oy:0},{ox:-d,oy:0},{ox:0,oy:-u},{ox:-d,oy:-u},{ox:-d/2,oy:-u/2}];let x=null,v=0;t:for(const t of y){let s={x:e+t.ox,y:n+t.oy,width:d,height:u};if(g(s),zt(s.x,o.x)||zt(s.y,o.y)||Ot(s.x+s.width,o.x+o.width)||Ot(s.y+s.height,o.y+o.height))continue;for(const t of p)if(Lt(s,t))continue t;const i=1e-6,r=1e3;let a=!0,l=0;for(;a&&l<r;){l++,a=!1;const t={bounds:o,blockers:p,maxAspect:c};g(Gt({rect:s,bounds:o}));const e=Kt({...t,r:s});e>i&&(s={...s,width:s.width+e},g(s),a=!0),g(Zt({rect:s,bounds:o}));const n=Qt({...t,r:s});n>i&&(s={...s,height:s.height+n},g(s),a=!0),g(qt({rect:s,bounds:o}));const r=te({...t,r:s});r>i&&(s={x:s.x-r,y:s.y,width:s.width+r,height:s.height},g(s),a=!0),g(Jt({rect:s,bounds:o}));const h=ee({...t,r:s});h>i&&(s={x:s.x,y:s.y-h,width:s.width,height:s.height+h},g(s),a=!0)}if(s.width+wt>=h.width&&s.height+wt>=h.height){const t=s.width*s.height;t>v&&(x=s,v=t)}}return x}function ie(t){const e=Math.max(t.width,t.height);return[e/8,e/16,e/32]}function re(t){const e={minX:t.point.x,minY:t.point.y,maxX:t.point.x,maxY:t.point.y};for(let n=0;n<t.layerCount;n++){const s=t.obstacleIndexByLayer[n],o=!!s&&s.search(e).length>0,i=t.placedIndexByLayer[n],r=!!i&&i.search(e).length>0;if(!o&&!r)return!1}return!0}function ae(t){const{x:e,y:n,z:s,layerCount:o,minSpan:i,maxSpan:r,obstacleIndexByLayer:a,additionalBlockersByLayer:c}=t,h=t=>{const s={minX:e,minY:n,maxX:e,maxY:n},o=a[t];if(o&&o.search(s).length>0)return!1;return!(c?.[t]??[]).some(t=>{return(o={x:e,y:n}).x>=(s=t).x-wt&&o.x<=s.x+s.width+wt&&o.y>=s.y-wt&&o.y<=s.y+s.height+wt;var s,o})};let l=s,d=s;for(;l-1>=0&&h(l-1);)l--;for(;d+1<o&&h(d+1);)d++;if("number"==typeof r){const t=Rt(r,1,o);for(;d-l+1>t;)s-l>d-s?l++:d--}const u=[];for(let t=l;t<=d;t++)u.push(t);return u.length>=i?u:[]}function ce(t){const{lineStart:e,lineEnd:n,coveringIntervals:s,minSegmentLength:o}=t;if(0===s.length){return[{start:e,end:n,center:(e+n)/2}]}const i=[...s].sort((t,e)=>t.start-e.start),r=[];let a={...i[0]};for(let t=1;t<i.length;t++){const e=i[t];e.start<=a.end+wt?a.end=Math.max(a.end,e.end):(r.push(a),a={...e})}r.push(a);const c=[];if(r[0].start>e+wt){const t=e,n=r[0].start;n-t>=o&&c.push({start:t,end:n,center:(t+n)/2})}for(let t=0;t<r.length-1;t++){const e=r[t].end,n=r[t+1].start;n-e>=o&&c.push({start:e,end:n,center:(e+n)/2})}if(r[r.length-1].end<n-wt){const t=r[r.length-1].end,e=n;e-t>=o&&c.push({start:t,end:e,center:(t+e)/2})}return c}function he(t){const{bounds:e,minSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=[],c=Math.max(.15*n,3*wt),h=new Set;function l(t){const{x:n,y:c,z:l}=t;if(n<e.x+wt||c<e.y+wt||n>e.x+e.width-wt||c>e.y+e.height-wt)return;if(function(t){return re({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:t})}({x:n,y:c}))return;const d=[...o[l]?.all()??[],...r[l]??[]],u=Math.min(Ft({x:n,y:c},e),...d.length?d.map(t=>Ft({x:n,y:c},t)):[1/0]),p=(t=>`${t.z}|${t.x.toFixed(6)}|${t.y.toFixed(6)}`)({x:n,y:c,z:l});if(h.has(p))return;h.add(p);const f=ae({x:n,y:c,z:l,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});a.push({x:n,y:c,z:l,distance:u,zSpanLen:f.length,isEdgeSeed:!0})}for(let t=0;t<s;t++){const s=[...o[t]?.all()??[],...r[t]??[]],i=[{x:e.x+c,y:e.y+c},{x:e.x+e.width-c,y:e.y+c},{x:e.x+c,y:e.y+e.height-c},{x:e.x+e.width-c,y:e.y+e.height-c}];for(const e of i)l({x:e.x,y:e.y,z:t});const a=e.y+c,h=s.filter(t=>t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),d=ce({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:h,minSegmentLength:.5*n});for(const e of d){const s=e.end-e.start;s>=n&&(l({x:e.center,y:a,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:a,z:t}),l({x:e.end-.4*n,y:a,z:t})))}const u=e.y+e.height-c,p=s.filter(t=>t.y<=u&&t.y+t.height>=u).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),f=ce({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:p,minSegmentLength:.5*n});for(const e of f){const s=e.end-e.start;s>=n&&(l({x:e.center,y:u,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:u,z:t}),l({x:e.end-.4*n,y:u,z:t})))}const m=e.x+c,g=s.filter(t=>t.x<=m&&t.x+t.width>=m).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),y=ce({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:g,minSegmentLength:.5*n});for(const e of y){const s=e.end-e.start;s>=n&&(l({x:m,y:e.center,z:t}),s>1.5*n&&(l({x:m,y:e.start+.4*n,z:t}),l({x:m,y:e.end-.4*n,z:t})))}const x=e.x+e.width-c,v=s.filter(t=>t.x<=x&&t.x+t.width>=x).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),b=ce({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:v,minSegmentLength:.5*n});for(const e of b){const s=e.end-e.start;s>=n&&(l({x:x,y:e.center,z:t}),s>1.5*n&&(l({x:x,y:e.start+.4*n,z:t}),l({x:x,y:e.end-.4*n,z:t})))}for(const o of s){const i=o.x-c;if(i>e.x+wt&&i<e.x+e.width-wt){const e=s.filter(t=>t!==o&&t.x<=i&&t.x+t.width>=i).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),r=ce({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)l({x:i,y:e.center,z:t})}const r=o.x+o.width+c;if(r>e.x+wt&&r<e.x+e.width-wt){const e=s.filter(t=>t!==o&&t.x<=r&&t.x+t.width>=r).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),i=ce({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:r,y:e.center,z:t})}const a=o.y-c;if(a>e.y+wt&&a<e.y+e.height-wt){const e=s.filter(t=>t!==o&&t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ce({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:a,z:t})}const h=o.y+o.height+c;if(h>e.y+wt&&h<e.y+e.height-wt){const e=s.filter(t=>t!==o&&t.y<=h&&t.y+t.height>=h).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ce({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:h,z:t})}}}return a.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),a}var le=(t,e)=>({...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:e.zLayers});function de(t,e){const n=t.placed[e],{rect:s,zLayers:o}=n,i=t.layerCount,r=[],a=[];for(let n=0;n<t.placed.length;n++){if(n===e)continue;const c=t.placed[n];if(c.zLayers.length>=i)continue;const h=c.zLayers.filter(t=>o.includes(t));if(0===h.length)continue;if(!Lt(c.rect,s))continue;const l=Xt(c.rect,s);r.push(n);const d=c.zLayers.filter(t=>!o.includes(t));d.length>0&&a.push({rect:c.rect,zLayers:d});const u=Math.min(t.options.minSingle.width,t.options.minMulti.width),p=Math.min(t.options.minSingle.height,t.options.minMulti.height);for(const t of l)t.width+wt>=u&&t.height+wt>=p&&a.push({rect:t,zLayers:h.slice()})}const c=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY;r.sort((t,e)=>e-t).forEach(e=>{const n=t.placed.splice(e,1)[0];if(t.placedIndexByLayer)for(const e of n.zLayers){const s=t.placedIndexByLayer[e];s&&s.remove(le(n.rect,{zLayers:n.zLayers}),c)}});for(const e of a){t.placed.push(e);for(const n of e.zLayers)if(t.placedIndexByLayer){const s=t.placedIndexByLayer[n];s&&s.insert(le(e.rect,{zLayers:e.zLayers.slice()}))}}}var ue=t=>{const e=[{fill:"#dbeafe",stroke:"#3b82f6"},{fill:"#fef3c7",stroke:"#f59e0b"},{fill:"#d1fae5",stroke:"#10b981"},{fill:"#e9d5ff",stroke:"#a855f7"},{fill:"#fed7aa",stroke:"#f97316"},{fill:"#fecaca",stroke:"#ef4444"}];return e[Math.min(...t)%e.length]},pe=class extends N{constructor(t){super(),this.input=t}srj;layerNames;layerCount;bounds;options;boardVoidRects;gridIndex;candidates;placed;placedIndexByLayer;expansionIndex;edgeAnalysisDone;totalSeedsThisGrid;consumedSeedsThisGrid;_setup(){const t=this.input.simpleRouteJson,e=this.input.gridOptions??{},{layerNames:n,zIndexByName:s}=jt(t),o=Math.max(1,n.length,t.layerCount||1),i={x:t.bounds.minX,y:t.bounds.minY,width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},r=Math.max(.01,t.minTraceWidth||.15),a={...{gridSizes:[],initialCellRatio:.2,maxAspectRatio:3,minSingle:{width:2*r,height:2*r},minMulti:{width:4*r,height:4*r,minLayers:Math.min(2,Math.max(1,t.layerCount||1))},preferMultiLayer:!0,maxMultiLayerSpan:void 0},...e,gridSizes:e.gridSizes??ie(i)};this.srj=t,this.layerNames=n,this.layerCount=o,this.bounds=i,this.options=a,this.boardVoidRects=this.input.boardVoidRects,this.gridIndex=0,this.candidates=[],this.placed=[],this.placedIndexByLayer=Array.from({length:o},()=>new ot),this.expansionIndex=0,this.edgeAnalysisDone=!1,this.totalSeedsThisGrid=0,this.consumedSeedsThisGrid=0,this.stats={gridIndex:this.gridIndex}}_step(){this._stepGrid(),this.stats.gridIndex=this.gridIndex,this.stats.placed=this.placed.length}_stepGrid(){const{gridSizes:t,initialCellRatio:e,maxAspectRatio:n,minSingle:s,minMulti:o,preferMultiLayer:i,maxMultiLayerSpan:r}=this.options,a=t[this.gridIndex],c=function(t){const e=Array.from({length:t.layerCount},()=>[]);for(const n of t.placed)if(n.zLayers.length>=t.layerCount)for(const t of n.zLayers)e[t].push(n.rect);return e}({layerCount:this.layerCount,placed:this.placed});if(0===this.candidates.length&&0===this.consumedSeedsThisGrid&&(this.candidates=function(t){const{bounds:e,gridSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=new Map;for(let t=e.x;t<e.x+e.width;t+=n)for(let c=e.y;c<e.y+e.height;c+=n){if(Math.abs(t-e.x)<wt||Math.abs(c-e.y)<wt||t>e.x+e.width-n-wt||c>e.y+e.height-n-wt)continue;if(re({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:{x:t,y:c}}))continue;let h=[],l=0;for(let e=0;e<s;e++){const n=ae({x:t,y:c,z:e,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});n.length>h.length&&(h=n,l=e)}const d=h.length?h[Math.floor(h.length/2)]:l,u=[...o[d]?.all()??[],...r[d]??[]],p=Math.min(Ft({x:t,y:c},e),...u.length?u.map(e=>Ft({x:t,y:c},e)):[1/0]),f=`${t.toFixed(6)}|${c.toFixed(6)}`,m={x:t,y:c,z:d,distance:p,zSpanLen:h.length},g=a.get(f);(!g||m.zSpanLen>(g.zSpanLen??0)||m.zSpanLen===g.zSpanLen&&m.distance>g.distance)&&a.set(f,m)}const c=Array.from(a.values());return c.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),c}({bounds:this.bounds,gridSize:a,layerCount:this.layerCount,hardPlacedByLayer:c,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer}),this.totalSeedsThisGrid=this.candidates.length,this.consumedSeedsThisGrid=0),0===this.candidates.length){if(this.gridIndex+1<t.length)return this.gridIndex+=1,this.totalSeedsThisGrid=0,void(this.consumedSeedsThisGrid=0);if(!this.edgeAnalysisDone){const t=Math.min(s.width,s.height);return this.candidates=he({bounds:this.bounds,minSize:t,layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,hardPlacedByLayer:c}),this.edgeAnalysisDone=!0,this.totalSeedsThisGrid=this.candidates.length,void(this.consumedSeedsThisGrid=0)}return this.solved=!0,void(this.expansionIndex=0)}const h=this.candidates.shift();this.consumedSeedsThisGrid+=1;const l=ae({x:h.x,y:h.y,z:h.z,layerCount:this.layerCount,minSpan:o.minLayers,maxSpan:r,obstacleIndexByLayer:this.input.obstacleIndexByLayer,additionalBlockersByLayer:c}),d=[];l.length>=o.minLayers&&d.push({kind:"multi",layers:l,minReq:{width:o.width,height:o.height}}),d.push({kind:"single",layers:[h.z],minReq:{width:s.width,height:s.height}});const u=i?d:d.reverse();for(const t of u){const s=oe({startX:h.x,startY:h.y,gridSize:a,bounds:this.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:e,maxAspectRatio:n,minReq:t.minReq,zLayers:t.layers});if(!s)continue;const o={rect:s,zLayers:[...t.layers]},i=this.placed.push(o)-1;for(const e of t.layers){const t=this.placedIndexByLayer[e];t&&t.insert(le(s,{zLayers:o.zLayers}))}return de({layerCount:this.layerCount,placed:this.placed,options:this.options,placedIndexByLayer:this.placedIndexByLayer},i),void(this.candidates=this.candidates.filter(t=>!re({layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,point:{x:t.x,y:t.y}})))}}computeProgress(){if(this.solved)return 1;const t=this.options.gridSizes.length,e=this.gridIndex/(t+1),n=Math.max(1,this.totalSeedsThisGrid),s=n?this.consumedSeedsThisGrid/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){return{srj:this.srj,layerNames:this.layerNames,layerCount:this.layerCount,bounds:this.bounds,options:this.options,boardVoidRects:this.boardVoidRects,gridIndex:this.gridIndex,candidates:this.candidates,placed:this.placed,expansionIndex:this.expansionIndex,edgeAnalysisDone:this.edgeAnalysisDone,totalSeedsThisGrid:this.totalSeedsThisGrid,consumedSeedsThisGrid:this.consumedSeedsThisGrid}}visualize(){const t=[],e=[],n=[],s=this.srj??this.input.simpleRouteJson,o=s.bounds.minX,i=s.bounds.maxX,r=s.bounds.minY,a=s.bounds.maxY;s.outline&&s.outline.length>1?n.push({points:[...s.outline,s.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):t.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of s.obstacles??[])"rect"!==e.type&&"oval"!==e.type||t.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});if(this.boardVoidRects){let e=null;if(s.outline&&s.outline.length>0){const t=s.outline.map(t=>t.x),n=s.outline.map(t=>t.y),o=Math.min(...t),i=Math.min(...n);e={x:o,y:i,width:Math.max(...t)-o,height:Math.max(...n)-i}}for(const n of this.boardVoidRects)e&&!Lt(n,e)||t.push({center:{x:n.x+n.width/2,y:n.y+n.height/2},width:n.width,height:n.height,fill:"rgba(0, 0, 0, 0.5)",stroke:"none",label:"void"})}if(this.candidates?.length)for(const t of this.candidates)e.push({x:t.x,y:t.y,fill:"#9333ea",stroke:"#6b21a8",label:`z:${t.z}`});if(this.placed?.length)for(const e of this.placed){const n=ue(e.zLayers);t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,fill:n.fill,stroke:n.stroke,layer:`z${e.zLayers.join(",")}`,label:`free\nz:${e.zLayers.join(",")}`})}return{title:"RectDiff Grid",coordinateSystem:"cartesian",rects:t,points:e,lines:n}}};var fe=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY,me=class extends N{constructor(t){super(),this.input=t}placedIndexByLayer=[];_meshNodes=[];_setup(){this.stats={gridIndex:this.input.gridIndex},this.placedIndexByLayer=Array.from({length:this.input.layerCount},()=>new ot);for(const t of this.input.placed)for(const e of t.zLayers){const n=this.placedIndexByLayer[e];n&&n.insert(le(t.rect,{zLayers:t.zLayers}))}}_step(){this.solved||(this._stepExpansion(),this.stats.gridIndex=this.input.gridIndex,this.stats.placed=this.input.placed.length,this.input.expansionIndex>=this.input.placed.length&&this.finalizeIfNeeded())}_stepExpansion(){if(this.input.expansionIndex>=this.input.placed.length)return;const t=this.input.expansionIndex,e=this.input.placed[t],n=this.input.options.gridSizes[this.input.options.gridSizes.length-1],s=e.rect,o=oe({startX:e.rect.x+e.rect.width/2,startY:e.rect.y+e.rect.height/2,gridSize:n,bounds:this.input.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:0,maxAspectRatio:null,minReq:{width:e.rect.width,height:e.rect.height},zLayers:e.zLayers});if(o){this.input.placed[t]={rect:o,zLayers:e.zLayers};for(const t of e.zLayers){const n=this.placedIndexByLayer[t];n&&(n.remove(le(s,{zLayers:e.zLayers}),fe),n.insert(le(o,{zLayers:e.zLayers})))}de({layerCount:this.input.layerCount,placed:this.input.placed,options:this.input.options,placedIndexByLayer:this.placedIndexByLayer},t)}this.input.expansionIndex+=1}finalizeIfNeeded(){if(this.solved)return;const t=function(t){const e=t.placed.map(t=>({minX:t.rect.x,minY:t.rect.y,maxX:t.rect.x+t.rect.width,maxY:t.rect.y+t.rect.height,zLayers:[...t.zLayers].sort((t,e)=>t-e)})),{zIndexByName:n}=jt(t.srj),s=new Map;for(const e of t.srj.obstacles??[]){const t=Ht(e);if(!t)continue;const o=e.zLayers?.length&&e.zLayers.length>0?e.zLayers:Wt(e,n),i=`${t.x}:${t.y}:${t.width}:${t.height}`;let r=s.get(i);r||(r={rect:t,layers:new Set},s.set(i,r)),o.forEach(t=>r.layers.add(t))}for(const{rect:t,layers:n}of s.values())e.push({minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:Array.from(n).sort((t,e)=>t-e),isObstacle:!0});return e}({placed:this.input.placed,srj:this.input.srj,boardVoidRects:this.input.boardVoidRects});this._meshNodes=function(t){let e=0;const n=[];for(const s of t){const t=Math.max(0,s.maxX-s.minX),o=Math.max(0,s.maxY-s.minY);t<=0||o<=0||0===s.zLayers.length||n.push({capacityMeshNodeId:"cmn_"+e++,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:t,height:o,layer:"top",availableZ:s.zLayers.slice(),_containsObstacle:s.isObstacle,_containsTarget:s.isObstacle})}return n}(t),this.solved=!0}computeProgress(){if(this.solved)return 1;const t=this.input.options.gridSizes.length,e=t/(t+1),n=Math.max(1,this.input.placed.length),s=n?this.input.expansionIndex/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){if(this.solved)return{meshNodes:this._meshNodes};return{meshNodes:this.input.placed.map((t,e)=>({capacityMeshNodeId:`expand-preview-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers.slice(),layer:`z${t.zLayers.join(",")}`}))}}visualize(){const t=[];for(const e of this.input.placed??[])t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,stroke:"rgba(37, 99, 235, 0.9)",fill:"rgba(191, 219, 254, 0.5)",layer:`z${e.zLayers.join(",")}`,label:`expanded\nz:${e.zLayers.join(",")}`});return{title:"RectDiff Expansion",coordinateSystem:"cartesian",rects:t,points:[],lines:[]}}},ge=class extends _{rectDiffSeedingSolver;rectDiffExpansionSolver;obstacleIndexByLayer;constructor(t){super(t);const{obstacleIndexByLayer:e}=(t=>{const{srj:e,boardVoidRects:n}=t,{layerNames:s,zIndexByName:o}=jt(e),i=Math.max(1,s.length,e.layerCount||1),r=(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.minX,e.bounds.maxY,e.bounds.minY,Array.from({length:i},()=>new ot)),a=(t,e)=>{const n={...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:[e]};r[e]?.insert(n)};if(e.outline&&e.outline.length>2)for(const t of n??[])for(let e=0;e<i;e++)a(t,e);for(const t of e.obstacles??[]){const e=Ht(t);if(!e)continue;const n=Wt(t,o),s=n.filter(t=>t<0||t>=i);if(s.length)throw new Error(`RectDiff: obstacle uses z-layer indices ${s.join(",")} outside 0-${i-1}`);t.zLayers&&0!==t.zLayers.length||!n.length||(t.zLayers=n);for(const t of n)a(e,t)}return{obstacleIndexByLayer:r}})({srj:t.simpleRouteJson,boardVoidRects:t.boardVoidRects});this.obstacleIndexByLayer=e}pipelineDef=[I("rectDiffSeedingSolver",pe,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,obstacleIndexByLayer:t.obstacleIndexByLayer,boardVoidRects:t.inputProblem.boardVoidRects}]),I("rectDiffExpansionSolver",me,t=>{const e=t.rectDiffSeedingSolver?.getOutput();if(!e)throw new Error("RectDiffSeedingSolver did not produce output");return[{srj:t.inputProblem.simpleRouteJson,layerNames:e.layerNames??[],boardVoidRects:t.inputProblem.boardVoidRects??[],layerCount:t.inputProblem.simpleRouteJson.layerCount,bounds:e.bounds,candidates:e.candidates,consumedSeedsThisGrid:e.placed.length,totalSeedsThisGrid:e.candidates.length,placed:e.placed,edgeAnalysisDone:e.edgeAnalysisDone,gridIndex:e.gridIndex,expansionIndex:e.expansionIndex,obstacleIndexByLayer:t.obstacleIndexByLayer,options:e.options}]})];getConstructorParams(){return[this.inputProblem]}getOutput(){if(this.rectDiffExpansionSolver)return this.rectDiffExpansionSolver.getOutput();if(this.rectDiffSeedingSolver){return{meshNodes:this.rectDiffSeedingSolver.getOutput().placed.map((t,e)=>({capacityMeshNodeId:`grid-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers,layer:`z${t.zLayers.join(",")}`}))}}return{meshNodes:[]}}visualize(){return this.rectDiffExpansionSolver?this.rectDiffExpansionSolver.visualize():this.rectDiffSeedingSolver?this.rectDiffSeedingSolver.visualize():{title:"RectDiff Grid Pipeline",coordinateSystem:"cartesian",rects:[],points:[],lines:[]}}};function ye(t,e="RectDiff"){const n=[],s=[],o=t.bounds.minX,i=t.bounds.maxX,r=t.bounds.minY,a=t.bounds.maxY;t.outline&&t.outline.length>1?s.push({points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):n.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of t.obstacles??[])"rect"!==e.type&&"oval"!==e.type||n.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});return{title:e,coordinateSystem:"cartesian",rects:n,points:[],lines:s}}var xe=class extends _{rectDiffGridSolverPipeline;gapFillSolver;boardVoidRects;pipelineDef=[I("rectDiffGridSolverPipeline",ge,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,boardVoidRects:t.boardVoidRects}]),I("gapFillSolver",Et,t=>[{meshNodes:t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],boardVoid:{boardVoidRects:t.boardVoidRects||[],layerCount:t.inputProblem.simpleRouteJson.layerCount||0}}])];_setup(){this.inputProblem.simpleRouteJson.outline&&(this.boardVoidRects=$t({x:this.inputProblem.simpleRouteJson.bounds.minX,y:this.inputProblem.simpleRouteJson.bounds.minY,width:this.inputProblem.simpleRouteJson.bounds.maxX-this.inputProblem.simpleRouteJson.bounds.minX,height:this.inputProblem.simpleRouteJson.bounds.maxY-this.inputProblem.simpleRouteJson.bounds.minY},this.inputProblem.simpleRouteJson.outline??[]))}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.gapFillSolver?.getOutput();return t?{meshNodes:t.outputNodes}:this.rectDiffGridSolverPipeline?this.rectDiffGridSolverPipeline.getOutput():{meshNodes:[]}}initialVisualize(){const t=ye(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Initial"),e=this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[];for(const n of e)t.rects.push({center:n.center,width:n.width,height:n.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t=ye(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Final"),{meshNodes:e}=this.getOutput(),n=new Set((this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[]).map(t=>t.capacityMeshNodeId));for(const s of e){const e=!n.has(s.capacityMeshNodeId);t.rects.push({center:s.center,width:s.width,height:s.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${s.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${s.capacityMeshNodeId}`,`z:${s.availableZ.join(",")}`].join("\n")})}return t}},ve=class{cacheHitsByPrefix={};cacheMissesByPrefix={};isSyncCache=!0;cacheHits=0;cacheMisses=0;cache=new Map;getCachedSolutionSync(t){const e=this.cache.get(t);if(void 0!==e){this.cacheHits++;const n=t.split(":")[0];return this.cacheHitsByPrefix[n]=(this.cacheHitsByPrefix[n]||0)+1,structuredClone(e)}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){this.cache.set(t,structuredClone(e))}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){this.cache.clear(),this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}getAllCacheKeys(){return Array.from(this.cache.keys())}},be="tscircuit_autorouter_cache_",Pe=class{isSyncCache=!0;cacheHits=0;cacheMisses=0;cacheHitsByPrefix={};cacheMissesByPrefix={};constructor(){}getKey(t){return`${be}${t}`}getCachedSolutionSync(t){if("undefined"==typeof localStorage)return;const e=this.getKey(t);try{const n=localStorage.getItem(e);if(null!==n){const e=JSON.parse(n);this.cacheHits++;const s=t.split(":")[0];return this.cacheHitsByPrefix[s]=(this.cacheHitsByPrefix[s]||0)+1,e}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}catch(n){console.error(`Error getting cached solution sync for ${e}:`,n),this.cacheMisses++;const s=t.split(":")[0];return void(this.cacheMissesByPrefix[s]=(this.cacheMissesByPrefix[s]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){if("undefined"==typeof localStorage)return;const n=this.getKey(t);try{const t=JSON.stringify(e);localStorage.setItem(n,t)}catch(t){console.error(`Error setting cached solution sync for ${n}:`,t),t instanceof DOMException&&("QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)&&console.warn(`LocalStorage quota exceeded. Failed to cache solution for ${n}. Consider clearing the cache.`)}}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){if("undefined"!=typeof localStorage)try{const t=[];for(let e=0;e<localStorage.length;e++){const n=localStorage.key(e);n?.startsWith(be)&&t.push(n)}t.forEach(t=>localStorage.removeItem(t)),console.log(`Cleared ${t.length} items from LocalStorage cache.`)}catch(t){console.error("Error clearing LocalStorage cache:",t)}finally{this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}}getAllCacheKeys(){const t=[];for(let e=0;e<1e4;e++){const n=localStorage.key(e);if(!n)break;n.includes(be)&&t.push(n)}return t}};function Se(){return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE||Ne(),globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE}function Me(){return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE||Ne(),globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE}function Ne(){globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE??=new Pe,globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE??=new ve}function Ie(t){const e={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};for(const n of t.portPoints)n.x<e.minX&&(e.minX=n.x),n.x>e.maxX&&(e.maxX=n.x),n.y<e.minY&&(e.minY=n.y),n.y>e.maxY&&(e.maxY=n.y);return e}var _e=(t,e)=>t<=e?[t,e]:[e,t],Ce=t=>`${t[0]}|${t[1]}`,Te=({portPointId:t,currentNodeId:e,inputNodes:n})=>{let s;if(t)for(const e of n){const n=e.portPoints.find(e=>e.portPointId===t);if(n?.connectionNodeIds){s=n.connectionNodeIds;break}}if(!s||2!==s.length)return[e,e];const[o,i]=s;return o&&i?_e(o,i):[e,e]},Ee=1e-6,we=(t,e)=>Math.abs(t-e)<=Ee,Re=({nodeAId:t,nodeBId:e,nodeBounds:n})=>{if(t===e)return null;const s=n.get(t),o=n.get(e);if(!s||!o)return null;const i=_e(t,e),r=Ce(i);if(we(s.maxX,o.minX)||we(o.maxX,s.minX)){const n=Math.max(s.minY,o.minY),a=Math.min(s.maxY,o.maxY),c=a-n;if(c>Ee){const h=we(s.maxX,o.minX)?s.maxX:s.minX;return{ownerNodeIds:i,ownerPairKey:r,orientation:"vertical",x1:h,y1:n,x2:h,y2:a,center:{x:h,y:(n+a)/2},length:c,nodeSideByOwnerId:we(s.maxX,o.minX)?{[t]:"right",[e]:"left"}:{[t]:"left",[e]:"right"}}}}if(we(s.maxY,o.minY)||we(o.maxY,s.minY)){const n=Math.max(s.minX,o.minX),a=Math.min(s.maxX,o.maxX),c=a-n;if(c>Ee){const h=we(s.maxY,o.minY)?s.maxY:s.minY;return{ownerNodeIds:i,ownerPairKey:r,orientation:"horizontal",x1:n,y1:h,x2:a,y2:h,center:{x:(n+a)/2,y:h},length:c,nodeSideByOwnerId:we(s.maxY,o.minY)?{[t]:"top",[e]:"bottom"}:{[t]:"bottom",[e]:"top"}}}}return null},Oe=({portPoint:t,ownerNodeIds:e,inputNodes:n})=>{for(const s of e){const e=n.find(t=>t.capacityMeshNodeId===s);if(e?._containsTarget)return!0;const o=e?.portPoints.find(e=>e.portPointId===t.portPointId);if(o?.connectionNodeIds?.some(t=>n.find(e=>e.capacityMeshNodeId===t)?._containsTarget))return!0}return!1},Ae=1e-6,ze=class extends N{constructor(t){super(),this.input=t;for(const e of t.nodeWithPortPoints)this.mapOfNodeIdToBounds.set(e.capacityMeshNodeId,Ie(e));const e=new Map;for(const n of t.nodeWithPortPoints)for(const s of n.portPoints){if(!s.portPointId)continue;const o=Te({portPointId:s.portPointId,currentNodeId:n.capacityMeshNodeId,inputNodes:t.inputNodesWithPortPoints}),i=Ce(o),r=this.mapOfOwnerPairToPortPoints.get(i)??[];r.some(t=>t.portPointId&&t.portPointId===s.portPointId)||r.push({...s,ownerNodeIds:o,ownerPairKey:i}),this.mapOfOwnerPairToPortPoints.set(i,r),e.set(i,o)}this.mapOfOwnerPairToSharedEdge=(({ownerPairs:t,nodeBounds:e})=>{const n=new Map;for(const s of t){const[t,o]=s;if(t===o)continue;const i=Re({nodeAId:t,nodeBId:o,nodeBounds:e});i&&n.set(Ce(s),i)}return n})({ownerPairs:Array.from(e.values()),nodeBounds:this.mapOfNodeIdToBounds}),this.ownerPairsToProcess=Array.from(this.mapOfOwnerPairToSharedEdge.keys()),this.ownerPairsToProcess.sort((t,e)=>{const n=this.mapOfOwnerPairToSharedEdge.get(t),s=this.mapOfOwnerPairToSharedEdge.get(e);return n.center.x-s.center.x||n.center.y-s.center.y})}getSolverName(){return"UniformPortDistributionSolver"}mapOfNodeIdToBounds=new Map;mapOfOwnerPairToPortPoints=new Map;mapOfOwnerPairToSharedEdge=new Map;ownerPairsToProcess=[];currentOwnerPairBeingProcessed=null;redistributedNodes=[];step(){if(0===this.ownerPairsToProcess.length)return this.rebuildNodes(),void(this.solved=!0);this.currentOwnerPairBeingProcessed=this.ownerPairsToProcess.shift();const t=this.currentOwnerPairBeingProcessed,e=this.mapOfOwnerPairToSharedEdge.get(t);if(!e)return;if((({sharedEdge:t,obstacles:e})=>{for(const n of e){const e=n.center.x-n.width/2,s=n.center.x+n.width/2,o=n.center.y-n.height/2,i=n.center.y+n.height/2;if("vertical"!==t.orientation){if(Math.abs(t.y1-o)<Ae||Math.abs(t.y1-i)<Ae){const n=Math.max(t.x1,e);if(Math.min(t.x2,s)-n>Ae)return!0}}else if(Math.abs(t.x1-e)<Ae||Math.abs(t.x1-s)<Ae){const e=Math.max(t.y1,o);if(Math.min(t.y2,i)-e>Ae)return!0}}return!1})({sharedEdge:e,obstacles:this.input.obstacles}))return;const n=this.mapOfOwnerPairToPortPoints.get(t)??[],s=[];for(const t of n)Oe({portPoint:t,ownerNodeIds:t.ownerNodeIds,inputNodes:this.input.inputNodesWithPortPoints})||s.push(t);const o=(({sharedEdge:t,portPoints:e})=>{if(0===e.length)return[];const n=new Map;for(const t of e){const e=t.z??0,s=n.get(e)??[];s.push(t),n.set(e,s)}const s=[],o=Array.from(n.keys()).sort((t,e)=>t-e);for(const e of o){const o=n.get(e),i=o.length;o.sort((e,n)=>"horizontal"===t.orientation?e.x-n.x:e.y-n.y);for(let e=0;e<i;e++){const n=(2*e+1)/(2*i),r="horizontal"===t.orientation?t.x1+t.length*n:t.x1,a="horizontal"===t.orientation?t.y1:t.y1+t.length*n;s.push({...o[e],x:r,y:a})}}return s})({sharedEdge:e,portPoints:s});this.mapOfOwnerPairToPortPoints.set(t,o)}rebuildNodes(){const t=new Map;for(const e of this.mapOfOwnerPairToPortPoints.values())for(const n of e)n.portPointId&&t.set(n.portPointId,{x:n.x,y:n.y});this.redistributedNodes=this.input.nodeWithPortPoints.map(e=>({...e,portPoints:e.portPoints.map(e=>{if(e.portPointId&&t.has(e.portPointId)){const n=t.get(e.portPointId);return{...e,x:n.x,y:n.y}}return e})}))}getOutput=()=>this.redistributedNodes;visualize(){return(({obstacles:t,nodeWithPortPoints:e,mapOfOwnerPairToPortPoints:n,mapOfOwnerPairToSharedEdge:s,ownerPairsToProcess:o,currentOwnerPairBeingProcessed:i,mapOfNodeIdToBounds:r})=>{const a=t.map(t=>({...t,fill:"#ec000070"})),c=[],h=[],l=new Map,d=new Map,u=new Map;for(const t of e)for(const e of t.portPoints)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0));for(const t of n.values())for(const e of t)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0),u.set(e.portPointId,`${e.ownerNodeIds[0]}&${e.ownerNodeIds[1]}`));e.forEach(t=>{const e=r.get(t.capacityMeshNodeId);if(e){const n=(e.minX+e.maxX)/2,s=(e.minY+e.maxY)/2,o=e.maxX-e.minX,i=e.maxY-e.minY;a.push({center:{x:n,y:s},width:o,height:i,fill:"#00000030",label:`${t.capacityMeshNodeId}`})}t.portPoints.forEach(e=>{if(!e.portPointId)return;const n=l.get(e.portPointId),s=d.get(e.portPointId)??0,o=u.get(e.portPointId)??`${t.capacityMeshNodeId}&${t.capacityMeshNodeId}`;c.push({x:n.x,y:n.y,label:`z:${s}\no:${o}`}),t.portPoints.forEach(t=>{if(t.portPointId&&e!==t&&e.connectionName===t.connectionName){const e=l.get(t.portPointId);h.push({points:[n,e],strokeColor:"#fff822c9"})}})})});for(const t of o){const e=s.get(t);e&&h.push({points:[{x:e.x1,y:e.y1},{x:e.x2,y:e.y2}],strokeColor:"orange",strokeWidth:.01})}if(i){const t=s.get(i);t&&(h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"red",strokeWidth:.03}),c.push({x:t.center.x,y:t.center.y,label:t.ownerPairKey}))}for(const t of s.values())h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"#33b5ff80",strokeWidth:.006});return{rects:a,lines:h,points:c}})({obstacles:this.input.obstacles,nodeWithPortPoints:this.input.nodeWithPortPoints,mapOfOwnerPairToPortPoints:this.mapOfOwnerPairToPortPoints,mapOfOwnerPairToSharedEdge:this.mapOfOwnerPairToSharedEdge,ownerPairsToProcess:this.ownerPairsToProcess,currentOwnerPairBeingProcessed:this.currentOwnerPairBeingProcessed,mapOfNodeIdToBounds:this.mapOfNodeIdToBounds})}},De=(t,e)=>{if(1===t&&1===e)return"inner1";if(t<0||t>=e)throw new Error(`Invalid z "${t}" for layer count: ${e}`);return 0===t?"top":t===e-1?"bottom":`inner${t}`},Le=(t,e)=>{const n=[];if(0===t.route.length)return n;let s=[],o=t.route[0].z;for(let i=0;i<t.route.length;i++){const r=t.route[i];if(r.z!==o){const i=De(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.vias.some(t=>Math.abs(t.x-r.x)<.001&&Math.abs(t.y-r.y)<.001)){const t=De(o,e),s=De(r.z,e);n.push({route_type:"via",x:r.x,y:r.y,from_layer:t,to_layer:s})}s=[r],o=r.z}else s.push(r)}const i=De(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.jumpers&&t.jumpers.length>0){const s=De(t.route[0]?.z??0,e);for(const e of t.jumpers)n.push({route_type:"jumper",start:e.start,end:e.end,footprint:e.footprint,layer:s})}return n};function Fe(){return Fe=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var s in n)({}).hasOwnProperty.call(n,s)&&(t[s]=n[s])}return t},Fe.apply(null,arguments)}function Ye(t,e){return(Ye=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function Xe(t){return(Xe=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function ke(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(ke=function(){return!!t})()}function $e(t){var e="function"==typeof Map?new Map:void 0;return $e=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(ke())return Reflect.construct.apply(null,arguments);var s=[null];s.push.apply(s,e);var o=new(t.bind.apply(t,s));return n&&Ye(o,n.prototype),o}(t,arguments,Xe(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),Ye(n,t)},$e(t)}var Be={1:"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\n\n",2:"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\n\n",3:"Passed an incorrect argument to a color function, please pass a string representation of a color.\n\n",4:"Couldn't generate valid rgb string from %s, it returned %s.\n\n",5:"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\n\n",6:"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\n\n",7:"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\n\n",8:"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\n\n",9:"Please provide a number of steps to the modularScale helper.\n\n",10:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",11:'Invalid value passed as base to modularScale, expected number or em string but got "%s"\n\n',12:'Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.\n\n',13:'Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.\n\n',14:'Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',15:'Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',16:"You must provide a template to this method.\n\n",17:"You passed an unsupported selector state to this method.\n\n",18:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",19:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",20:"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",21:"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n",22:"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n",23:"fontFace expects a name of a font-family.\n\n",24:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",25:"fontFace expects localFonts to be an array.\n\n",26:"fontFace expects fileFormats to be an array.\n\n",27:"radialGradient requries at least 2 color-stops to properly render.\n\n",28:"Please supply a filename to retinaImage() as the first argument.\n\n",29:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",30:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",31:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\n\n",32:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\n\n",33:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\n\n",34:"borderRadius expects a radius value as a string or number as the second argument.\n\n",35:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',36:"Property must be a string value.\n\n",37:"Syntax Error at %s.\n\n",38:"Formula contains a function that needs parentheses at %s.\n\n",39:"Formula is missing closing parenthesis at %s.\n\n",40:"Formula has too many closing parentheses at %s.\n\n",41:"All values in a formula must have the same unit or be unitless.\n\n",42:"Please provide a number of steps to the modularScale helper.\n\n",43:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",44:"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\n\n",45:"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\n\n",46:"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\n\n",47:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",48:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",49:"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",50:"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\n\n",51:"Expects the first argument object to have the properties prop, fromSize, and toSize.\n\n",52:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",53:"fontFace expects localFonts to be an array.\n\n",54:"fontFace expects fileFormats to be an array.\n\n",55:"fontFace expects a name of a font-family.\n\n",56:"linearGradient requries at least 2 color-stops to properly render.\n\n",57:"radialGradient requries at least 2 color-stops to properly render.\n\n",58:"Please supply a filename to retinaImage() as the first argument.\n\n",59:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",60:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",61:"Property must be a string value.\n\n",62:"borderRadius expects a radius value as a string or number as the second argument.\n\n",63:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',64:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\n\n",65:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\n\n",66:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\n\n",67:"You must provide a template to this method.\n\n",68:"You passed an unsupported selector state to this method.\n\n",69:'Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.\n\n',70:'Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.\n\n',71:'Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.\n\n',72:'Passed invalid base value %s to %s(), please pass a value like "12px" or 12.\n\n',73:"Please provide a valid CSS variable.\n\n",74:"CSS variable not found and no default was provided.\n\n",75:"important requires a valid style object, got a %s instead.\n\n",76:"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n\n",77:'remToPx expects a value in "rem" but you provided it in "%s".\n\n',78:'base must be set in "px" or "%" but you set it in "%s".\n'};function je(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var s,o=e[0],i=[];for(s=1;s<e.length;s+=1)i.push(e[s]);return i.forEach(function(t){o=o.replace(/%[a-z]/,t)}),o}var We=function(t){var e,n;function s(e){var n;if("production"===process.env.NODE_ENV)n=t.call(this,"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#"+e+" for more information.")||this;else{for(var s=arguments.length,o=new Array(s>1?s-1:0),i=1;i<s;i++)o[i-1]=arguments[i];n=t.call(this,je.apply(void 0,[Be[e]].concat(o)))||this}return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)}return n=t,(e=s).prototype=Object.create(n.prototype),e.prototype.constructor=e,Ye(e,n),s}($e(Error));function He(t,e){return t.substr(-e.length)===e}var Ue=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function Ve(t){return"string"!=typeof t?t:t.match(Ue)?parseFloat(t):t}var Ge=function(t){return function(e,n){void 0===n&&(n="16px");var s=e,o=n;if("string"==typeof e){if(!He(e,"px"))throw new We(69,t,e);s=Ve(e)}if("string"==typeof n){if(!He(n,"px"))throw new We(70,t,n);o=Ve(n)}if("string"==typeof s)throw new We(71,e,t);if("string"==typeof o)throw new We(72,n,t);return""+s/o+t}};Ge("em"),Ge("rem");function Ze(t){return Math.round(255*t)}function qe(t,e,n){return Ze(t)+","+Ze(e)+","+Ze(n)}function Je(t,e,n,s){if(void 0===s&&(s=qe),0===e)return s(n,n,n);var o=(t%360+360)%360/60,i=(1-Math.abs(2*n-1))*e,r=i*(1-Math.abs(o%2-1)),a=0,c=0,h=0;o>=0&&o<1?(a=i,c=r):o>=1&&o<2?(a=r,c=i):o>=2&&o<3?(c=i,h=r):o>=3&&o<4?(c=r,h=i):o>=4&&o<5?(a=r,h=i):o>=5&&o<6&&(a=i,h=r);var l=n-i/2;return s(a+l,c+l,h+l)}var Ke={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"639",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"};var Qe=/^#[a-fA-F0-9]{6}$/,tn=/^#[a-fA-F0-9]{8}$/,en=/^#[a-fA-F0-9]{3}$/,nn=/^#[a-fA-F0-9]{4}$/,sn=/^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i,on=/^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i,rn=/^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i,an=/^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;function cn(t){if("string"!=typeof t)throw new We(3);var e=function(t){if("string"!=typeof t)return t;var e=t.toLowerCase();return Ke[e]?"#"+Ke[e]:t}(t);if(e.match(Qe))return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16)};if(e.match(tn)){var n=parseFloat((parseInt(""+e[7]+e[8],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16),alpha:n}}if(e.match(en))return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16)};if(e.match(nn)){var s=parseFloat((parseInt(""+e[4]+e[4],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16),alpha:s}}var o=sn.exec(e);if(o)return{red:parseInt(""+o[1],10),green:parseInt(""+o[2],10),blue:parseInt(""+o[3],10)};var i=on.exec(e.substring(0,50));if(i)return{red:parseInt(""+i[1],10),green:parseInt(""+i[2],10),blue:parseInt(""+i[3],10),alpha:parseFloat(""+i[4])>1?parseFloat(""+i[4])/100:parseFloat(""+i[4])};var r=rn.exec(e);if(r){var a="rgb("+Je(parseInt(""+r[1],10),parseInt(""+r[2],10)/100,parseInt(""+r[3],10)/100)+")",c=sn.exec(a);if(!c)throw new We(4,e,a);return{red:parseInt(""+c[1],10),green:parseInt(""+c[2],10),blue:parseInt(""+c[3],10)}}var h=an.exec(e.substring(0,50));if(h){var l="rgb("+Je(parseInt(""+h[1],10),parseInt(""+h[2],10)/100,parseInt(""+h[3],10)/100)+")",d=sn.exec(l);if(!d)throw new We(4,e,l);return{red:parseInt(""+d[1],10),green:parseInt(""+d[2],10),blue:parseInt(""+d[3],10),alpha:parseFloat(""+h[4])>1?parseFloat(""+h[4])/100:parseFloat(""+h[4])}}throw new We(5)}function hn(t){return function(t){var e,n=t.red/255,s=t.green/255,o=t.blue/255,i=Math.max(n,s,o),r=Math.min(n,s,o),a=(i+r)/2;if(i===r)return void 0!==t.alpha?{hue:0,saturation:0,lightness:a,alpha:t.alpha}:{hue:0,saturation:0,lightness:a};var c=i-r,h=a>.5?c/(2-i-r):c/(i+r);switch(i){case n:e=(s-o)/c+(s<o?6:0);break;case s:e=(o-n)/c+2;break;default:e=(n-s)/c+4}return e*=60,void 0!==t.alpha?{hue:e,saturation:h,lightness:a,alpha:t.alpha}:{hue:e,saturation:h,lightness:a}}(cn(t))}var ln=function(t){return 7===t.length&&t[1]===t[2]&&t[3]===t[4]&&t[5]===t[6]?"#"+t[1]+t[3]+t[5]:t};function dn(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function un(t){return dn(Math.round(255*t))}function pn(t,e,n){return ln("#"+un(t)+un(e)+un(n))}function fn(t,e,n){return Je(t,e,n,pn)}function mn(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return ln("#"+dn(t)+dn(e)+dn(n));if("object"==typeof t&&void 0===e&&void 0===n)return ln("#"+dn(t.red)+dn(t.green)+dn(t.blue));throw new We(6)}function gn(t,e,n,s){if("string"==typeof t&&"number"==typeof e){var o=cn(t);return"rgba("+o.red+","+o.green+","+o.blue+","+e+")"}if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?mn(t,e,n):"rgba("+t+","+e+","+n+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?mn(t.red,t.green,t.blue):"rgba("+t.red+","+t.green+","+t.blue+","+t.alpha+")";throw new We(7)}function yn(t){if("object"!=typeof t)throw new We(8);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&"number"==typeof t.alpha}(t))return gn(t);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return mn(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&"number"==typeof t.alpha}(t))return function(t,e,n,s){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?fn(t,e,n):"rgba("+Je(t,e,n)+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?fn(t.hue,t.saturation,t.lightness):"rgba("+Je(t.hue,t.saturation,t.lightness)+","+t.alpha+")";throw new We(2)}(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return function(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return fn(t,e,n);if("object"==typeof t&&void 0===e&&void 0===n)return fn(t.hue,t.saturation,t.lightness);throw new We(1)}(t);throw new We(8)}function xn(t,e,n){return function(){var s=n.concat(Array.prototype.slice.call(arguments));return s.length>=e?t.apply(this,s):xn(t,e,s)}}function vn(t){return xn(t,t.length,[])}vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{hue:n.hue+parseFloat(t)}))});function bn(t,e,n){return Math.max(t,Math.min(e,n))}vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{lightness:bn(0,1,n.lightness-parseFloat(t))}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{saturation:bn(0,1,n.saturation-parseFloat(t))}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{lightness:bn(0,1,n.lightness+parseFloat(t))}))});var Pn=vn(function(t,e,n){if("transparent"===e)return n;if("transparent"===n)return e;if(0===t)return n;var s=cn(e),o=Fe({},s,{alpha:"number"==typeof s.alpha?s.alpha:1}),i=cn(n),r=Fe({},i,{alpha:"number"==typeof i.alpha?i.alpha:1}),a=o.alpha-r.alpha,c=2*parseFloat(t)-1,h=((c*a===-1?c:c+a)/(1+c*a)+1)/2,l=1-h;return gn({red:Math.floor(o.red*h+r.red*l),green:Math.floor(o.green*h+r.green*l),blue:Math.floor(o.blue*h+r.blue*l),alpha:o.alpha*parseFloat(t)+r.alpha*(1-parseFloat(t))})});vn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(Fe({},n,{alpha:bn(0,1,(100*("number"==typeof n.alpha?n.alpha:1)+100*parseFloat(t))/100)}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{saturation:bn(0,1,n.saturation+parseFloat(t))}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{hue:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{lightness:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{saturation:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:Pn(parseFloat(t),"rgb(0, 0, 0)",e)});vn(function(t,e){return"transparent"===e?e:Pn(parseFloat(t),"rgb(255, 255, 255)",e)});var Sn=vn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(Fe({},n,{alpha:bn(0,1,+(100*("number"==typeof n.alpha?n.alpha:1)-100*parseFloat(t)).toFixed(2)/100)}))}),Mn=["blue","orange","purple","cyan","magenta","yellowgreen","darkgoldenrod","deeppink"],Nn=(t,e)=>{const n={};for(let s=0;s<t.connections.length;s++){const o=t.connections[s],i=e?.getNetConnectedToId(o.name);i&&!n[i]&&(n[i]=`hsl(${300*s/t.connections.length}, 100%, 50%)`),n[o.name]=(i?n[i]:null)??`hsl(${340*s/t.connections.length}, 100%, 50%)`}return n},In=(t,e)=>{try{return Sn(e,t)}catch(e){return console.error(e),t}},_n=(t,e=1)=>{if(!t)return"rgba(0, 0, 0, 0.5)";const n=300*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)/t.length;return e<1?`hsla(${n}, 100%, 50%, ${e})`:`hsl(${n}, 100%, 50%)`};function Cn(t){return"layers"in t&&Array.isArray(t.layers)}function Tn(t){return Cn(t)?t.layers[0]:t.layer}function En(t){return Cn(t)?t.layers:[t.layer]}var wn={"0603":{length:1.65,width:.95,padLength:.8,padWidth:.95},1206:{length:3.2,width:1.6,padLength:.6,padWidth:1.6},"1206x4_pair":{length:2.7,width:.5,padLength:.8,padWidth:.5}},Rn=(t,e)=>"top"===t?0:"bottom"===t?e-1:parseInt(t.slice(5)),On=t=>{const e=[],n=[],s=[],o=[],i=Nn(t),r=(t.minViaDiameter??.3)/2;if(t.connections)for(const e of t.connections)for(const t of e.pointsToConnect){const n=En(t);s.push({x:t.x,y:t.y,color:i[e.name],layer:n[0]??("z"in t?De(t.z,2):"top"),label:`${e.name} (${n.join(",")})`})}if(t.traces)for(const s of t.traces){let a=t.minTraceWidth;const c=s.route.filter(t=>"jumper"===t.route_type),h=(t,e)=>{const n=.01;for(const s of c){const o=Math.abs(t.x-s.start.x)<n&&Math.abs(t.y-s.start.y)<n&&Math.abs(e.x-s.end.x)<n&&Math.abs(e.y-s.end.y)<n,i=Math.abs(t.x-s.end.x)<n&&Math.abs(t.y-s.end.y)<n&&Math.abs(e.x-s.start.x)<n&&Math.abs(e.y-s.start.y)<n;if(o||i)return!0}return!1};for(let t=0;t<s.route.length-1;t++){const c=s.route[t],l=s.route[t+1];if("via"===c.route_type)n.push({center:{x:c.x,y:c.y},radius:r,fill:"blue",stroke:"none",layer:"z0,1"});else if("jumper"===c.route_type){const t=i[s.connection_name]??"rgba(255, 165, 0, 0.8)",n=c.footprint,r=wn["1206x4_pair"===n?"1206x4_pair":"0603"]??wn["0603"],a=c.end.x-c.start.x,h=c.end.y-c.start.y,l=Math.abs(a)>Math.abs(h),d=l?r.padLength:r.padWidth,u=l?r.padWidth:r.padLength;o.push({center:c.start,width:d,height:u,fill:In(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),o.push({center:c.end,width:d,height:u,fill:In(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),e.push({points:[c.start,c.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"})}else if("wire"===c.route_type&&"wire"===l.route_type&&l.layer===c.layer){if(h({x:c.x,y:c.y},{x:l.x,y:l.y}))continue;a=c.width;const t=i[s.connection_name],n="top"===c.layer,o=t??{top:"red",bottom:"blue",inner1:"green",inner2:"yellow"}[c.layer];e.push({points:[{x:c.x,y:c.y},{x:l.x,y:l.y}],layer:`z${Rn(c.layer,2)}`,strokeWidth:a,strokeColor:n?o:In(o,.5),...n?{}:{strokeDash:"3 2"}})}}}for(const e of t.obstacles)o.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255,0,0,0.5)",layer:`z${e.layers.map(t=>Rn(t,2)).join(",")}`});if(t.jumpers)for(const e of t.jumpers)for(const t of e.pads)o.push({center:t.center,width:t.width,height:t.height,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:"jumper"});return{rects:o,circles:n,lines:e,points:s}},An=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){this.netMap[n].push(...this.netMap[e]),this.netMap[e]=this.netMap[n];for(const t of this.netMap[n])this.idToNetMap[t]=n}}for(const t of e)this.netMap[n].includes(t)||this.netMap[n].push(t),this.idToNetMap[t]=n}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){const e=this.getNetConnectedToId(t[0]);for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}},zn=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)}`,Dn=t=>{const e=new An({});for(const n of t.connections){if(n.rootConnectionName&&e.addConnections([[n.name,n.rootConnectionName]]),n.netConnectionName&&e.addConnections([[n.name,n.netConnectionName]]),n.mergedConnectionNames)for(const t of n.mergedConnectionNames)e.addConnections([[n.name,t]]);for(const s of n.pointsToConnect)e.addConnections([[n.name,`${zn(s)}:${"layers"in s?s.layers.map(e=>Rn(e,t.layerCount)).sort().join("-"):Rn(s.layer,t.layerCount)}`]]),"pcb_port_id"in s&&s.pcb_port_id&&e.addConnections([[n.name,s.pcb_port_id]])}for(const n of t.obstacles){const s=n.offBoardConnectsTo??[],o=Array.from(new Set([n.obstacleId,...n.connectedTo,...s,`${zn(n.center)}:${n.layers.map(e=>Rn(e,t.layerCount)).sort().join("-")}`].filter(Boolean)));o.length>0&&e.addConnections([o])}return e},Ln=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};cacheHit;cacheKey;cacheToSolveSpaceTransform;getSolverName(){return this.constructor.name}step(){if(!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,console.error(this.error),this.failed=!0,t}!this.solved&&this.iterations>this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations (MAX_ITERATIONS=${this.MAX_ITERATIONS})`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Fn(t){const e=new Map;for(const n of t)for(const t of n.nodeIds)e.set(t,[...e.get(t)??[],n]);return e}var Yn=class extends Ln{getSolverName(){return"AvailableSegmentPointSolver"}nodes;edges;traceWidth;obstacleMargin;minPortSpacing;nodeMap;nodeEdgeMap;sharedEdgeSegments=[];edgeSegmentMap=new Map;portPointMap=new Map;colorMap;shouldReturnCrampedPortPoints;constructor({nodes:t,edges:e,traceWidth:n,obstacleMargin:s,colorMap:o,shouldReturnCrampedPortPoints:i}){super(),this.nodes=t,this.edges=e,this.traceWidth=n,this.obstacleMargin=s??.15,this.shouldReturnCrampedPortPoints=i,this.minPortSpacing=this.traceWidth+this.obstacleMargin,this.colorMap=o??{},this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(e),this.MAX_ITERATIONS=1}_step(){this.computeAllSharedEdgeSegments(),this.solved=!0}computeAllSharedEdgeSegments(){for(const t of this.edges){const[e,n]=t.nodeIds,s=this.nodeMap.get(e),o=this.nodeMap.get(n);if(!s||!o)continue;const i=this.computeSharedEdgeSegment(t,s,o);if(i){this.sharedEdgeSegments.push(i),this.edgeSegmentMap.set(t.capacityMeshEdgeId,i);for(const t of i.portPoints)this.portPointMap.set(t.segmentPortPointId,t)}}}computeSharedEdgeSegment(t,e,n){const s=this.findOverlappingSegment(e,n);if(!s)return null;const o=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===o.length)return null;const i=Math.sqrt((s.end.x-s.start.x)**2+(s.end.y-s.start.y)**2),r=3*this.minPortSpacing/4,a=Math.max(0,i-2*r);if(a<=0&&!e._containsTarget&&!n._containsTarget){if(!this.shouldReturnCrampedPortPoints)return null;const i=[];for(const r of o)i.push({segmentPortPointId:`${t.capacityMeshEdgeId}_pp0_z${r}_cramped`,x:(s.start.x+s.end.x)/2,y:(s.start.y+s.end.y)/2,availableZ:[r],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:0,cramped:!0});return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:i}}let c=Math.max(1,Math.floor(a/this.minPortSpacing)+1);if(e._offBoardConnectionId||n._offBoardConnectionId){if(e._offBoardConnectionId&&!n._offBoardConnectionId){if(this.shouldSkipOffBoardPortPoint(e,n))return null}else if(n._offBoardConnectionId&&!e._offBoardConnectionId&&this.shouldSkipOffBoardPortPoint(n,e))return null;c=1}const h=[],l=s.end.x-s.start.x,d=s.end.y-s.start.y,u=(s.start.x+s.end.x)/2,p=(s.start.y+s.end.y)/2;c>5&&(c=5+Math.floor(c/4));const f=[];for(let t=0;t<c;t++){let e;e=0===i||1===c?.5:(r+a*t/(c-1))/i;const n=s.start.x+l*e,o=s.start.y+d*e,h=Math.sqrt((n-u)**2+(o-p)**2);f.push({x:n,y:o,distToCenter:h})}const m=f.reduce((t,e)=>e.distToCenter<t.distToCenter?e:t);for(let s=0;s<c;s++){const{x:i,y:r}=f[s],a=Math.sqrt((i-m.x)**2+(r-m.y)**2);for(const c of o){const o={segmentPortPointId:`${t.capacityMeshEdgeId}_pp${s}_z${c}`,x:i,y:r,availableZ:[c],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:a,cramped:!1};h.push(o)}}return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:h}}shouldSkipOffBoardPortPoint(t,e){const n=this.nodeEdgeMap.get(e.capacityMeshNodeId)??[];for(const s of n){const n=s.nodeIds[0]===e.capacityMeshNodeId?s.nodeIds[1]:s.nodeIds[0];if(n===t.capacityMeshNodeId)continue;const o=this.nodeMap.get(n);if(o?._offBoardConnectionId!==t._offBoardConnectionId)continue;if(2!==this.nodes.filter(e=>e._offBoardConnectionId===t._offBoardConnectionId).length)continue;const i={x:(t.center.x+o.center.x)/2,y:(t.center.y+o.center.y)/2};if(i.x>=e.center.x-e.width/2&&i.x<=e.center.x+e.width/2&&i.y>=e.center.y-e.height/2&&i.y<=e.center.y+e.height/2)return!0}return!1}findOverlappingSegment(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)},o=n.end-n.start,i=s.end-s.start;if(o<-1e-4||i<-1e-4)return null;if(o<i){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}getAvailablePortPointsBetweenNodes(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?s.portPoints.filter(t=>null===t.connectionName):[]}getPortPointsForEdge(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?.portPoints??[]}assignPortPoint(t,e,n){const s=this.portPointMap.get(t);return!!s&&(null===s.connectionName&&(s.connectionName=e,s.rootConnectionName=n,!0))}releasePortPoint(t){const e=this.portPointMap.get(t);return!!e&&(e.connectionName=null,e.rootConnectionName=void 0,!0)}getAvailablePortCountForEdge(t,e){return this.getAvailablePortPointsBetweenNodes(t,e).length}getOutput(){return this.sharedEdgeSegments}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.sharedEdgeSegments){t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.5)"});for(const n of e.portPoints){const e=n.connectionName?this.colorMap[n.connectionName]??"blue":"rgba(0, 200, 0, 0.7)";n.cramped?t.rects.push({center:{x:n.x,y:n.y},width:.1,height:.1,fill:e,layer:`z${n.availableZ.join(",")}`,label:`cramped ${n.segmentPortPointId}`}):t.circles.push({center:{x:n.x,y:n.y},radius:this.traceWidth/2,fill:e,layer:`z${n.availableZ.join(",")}`,label:[n.segmentPortPointId,n.connectionName,n.availableZ.join(","),`cd: ${n.distToCentermostPortOnZ}`,`connects: ${n.nodeIds.join(",")}`].filter(Boolean).join("\n")})}}return t}};function Xn(t,e){const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=e.center.x-e.width/2,a=e.center.x+e.width/2,c=e.center.y-e.height/2,h=e.center.y+e.height/2,l=.001,d=(Math.abs(s-r)<l||Math.abs(n-a)<l)&&Math.min(i,h)-Math.max(o,c)>=l,u=(Math.abs(i-c)<l||Math.abs(o-h)<l)&&Math.min(s,a)-Math.max(n,r)>=l;return d||u}var kn=class extends Ln{constructor(t){super(),this.nodes=t,this.edges=[]}getSolverName(){return"CapacityMeshEdgeSolver"}edges;nodeMap;getNextCapacityMeshEdgeId(){return`ce${this.edges.length}`}_step(){this.edges=[];for(let t=0;t<this.nodes.length;t++)for(let e=t+1;e<this.nodes.length;e++){!(this.nodes[t]._strawNode&&this.nodes[e]._strawNode&&this.nodes[t]._strawParentCapacityMeshNodeId===this.nodes[e]._strawParentCapacityMeshNodeId)&&Xn(this.nodes[t],this.nodes[e])&&this.doNodesHaveSharedLayer(this.nodes[t],this.nodes[e])&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[this.nodes[t].capacityMeshNodeId,this.nodes[e].capacityMeshNodeId]})}this.handleTargetNodes(),this.solved=!0}handleTargetNodes(){const t=this.nodes.filter(t=>t._containsTarget);for(const e of t){if(this.edges.some(t=>t.nodeIds.includes(e.capacityMeshNodeId)))continue;let t=null,n=1/0;for(const s of this.nodes){if(s._containsObstacle)continue;if(s._containsTarget)continue;const o=k(e.center,s.center);o<n&&(n=o,t=s)}t&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[e.capacityMeshNodeId,t.capacityMeshNodeId]})}}doNodesHaveSharedLayer(t,e){return t.availableZ.some(t=>e.availableZ.includes(t))}visualize(){const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const t=Math.min(...n.availableZ),o=Math.min(...s.availableZ),i={x:n.center.x+t*n.width*.05,y:n.center.y-t*n.width*.05},r={x:s.center.x+o*s.width*.05,y:s.center.y-o*s.width*.05},a=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${a.join(",")}`,points:[i,r],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5"})}}return e}},$n=class{constructor(t){this.nodes=t,this.buckets=new Map;for(const e of t){const t=e.center.x-e.width/2,n=e.center.y-e.height/2,s=e.center.x+e.width/2,o=e.center.y+e.height/2;for(let i=t;i<=s;i+=this.CELL_SIZE)for(let t=n;t<=o;t+=this.CELL_SIZE){const n=this.getBucketKey(i,t),s=this.buckets.get(n);s?s.push(e):this.buckets.set(n,[e])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t.capacityMeshNodeId)||(i.add(t.capacityMeshNodeId),o.push(t))}return o}},Bn=class extends kn{constructor(t){super(t),this.nodes=t,this.MAX_ITERATIONS=1e7,this.nodeTree=new $n(this.nodes),this.currentNodeIndex=0,this.edgeSet=new Set}getSolverName(){return"CapacityMeshEdgeSolver2_NodeTreeOptimization"}nodeTree;currentNodeIndex;edgeSet;_step(){if(this.currentNodeIndex>=this.nodes.length)return this.handleTargetNodes(),void(this.solved=!0);const t=this.nodes[this.currentNodeIndex],e=this.nodeTree.getNodesInArea(t.center.x,t.center.y,2*t.width,2*t.height);for(const n of e){if(!Xn(t,n))continue;const e=t._strawNode&&n._strawNode&&t._strawParentCapacityMeshNodeId===n._strawParentCapacityMeshNodeId;t.capacityMeshNodeId===n.capacityMeshNodeId||e||!this.doNodesHaveSharedLayer(t,n)||this.edgeSet.has(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`)||(this.edgeSet.add(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`),this.edgeSet.add(`${n.capacityMeshNodeId}-${t.capacityMeshNodeId}`),this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[t.capacityMeshNodeId,n.capacityMeshNodeId]}))}this.currentNodeIndex++}},jn=(...t)=>{const e={points:[],lines:[],circles:[],rects:[]};return t.forEach((t,n)=>{t&&(t.lines&&(e.lines=[...e.lines||[],...t.lines.map(t=>({...t,step:n}))]),t.points&&(e.points=[...e.points||[],...t.points.map(t=>({...t,step:n}))]),t.circles&&(e.circles=[...e.circles||[],...t.circles.map(t=>({...t,step:n}))]),t.rects&&(e.rects=[...e.rects||[],...t.rects.map(t=>({...t,step:n}))]))}),e};function Wn(t,e,n){const s=[];let o=null;for(let i=0;i<t.length;i++){const r=t[i];o?o.z===r.z?o.points.push({x:r.x,y:r.y}):(s.push(o),o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n}):o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n},i===t.length-1&&o&&s.push(o)}return s}import Hn from"object-hash";function Un(t){let e=t;for(let t=0;t<10;t++)e=16807*e%2147483647;let n=e;e=(69069*t+1)%2147483647;for(let t=0;t<10;t++)e=48271*e%2147483647;let s=e;return()=>{let t=n;n=s,t^=t<<23,t^=t>>>17,t^=s,t^=s>>>26,s=t;const e=(n+s)/4294967296;return e-Math.floor(e)}}var Vn={1:[[0]],2:[[0,1],[1,0]],3:[[0,1,2],[2,0,1],[1,0,2],[0,2,1],[1,2,0],[2,1,0]],4:[[0,1,2,3],[2,0,1,3],[1,3,2,0],[3,0,1,2],[0,2,1,3],[2,1,3,0],[3,0,2,1],[1,2,0,3],[3,1,0,2],[0,3,2,1],[2,3,0,1],[2,3,1,0],[1,2,3,0],[3,1,2,0],[0,1,3,2],[0,2,3,1],[0,3,1,2],[1,0,2,3],[1,0,3,2],[1,3,0,2],[2,0,3,1],[2,1,0,3],[3,2,0,1],[3,2,1,0]]};function Gn(t,e){if(0===e)return t;if(0===t.length)return t;if(t.length<=4){const n=Vn[t.length];return n[e%n.length].map(e=>t[e])}const n=Un(e),s=t.slice();for(let t=0;t<s.length;t++){const e=Math.floor(n()*s.length),o=Math.floor(n()*(t+1));[s[e],s[o]]=[s[o],s[e]]}return s}var Zn=t=>{let e=1/0;const n=t.portPoints;for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];if(o.z!==i.z)continue;if(o.rootConnectionName&&o.rootConnectionName===i.rootConnectionName)continue;const r=Math.sqrt((o.x-i.x)**2+(o.y-i.y)**2);e=Math.min(e,r)}return e===1/0?0:e},qn=class{heap=[];constructor(t){this.heap=[];for(const e of t)this.enqueue(e)}getLeftChildIndex(t){return 2*t+1}getRightChildIndex(t){return 2*t+2}getParentIndex(t){return Math.floor((t-1)/2)}hasLeftChild(t){return this.getLeftChildIndex(t)<this.heap.length}hasRightChild(t){return this.getRightChildIndex(t)<this.heap.length}hasParent(t){return this.getParentIndex(t)>=0}leftChild(t){return this.heap[this.getLeftChildIndex(t)]}rightChild(t){return this.heap[this.getRightChildIndex(t)]}parent(t){return this.heap[this.getParentIndex(t)]}swap(t,e){const n=this.heap[t];this.heap[t]=this.heap[e],this.heap[e]=n}dequeue(){if(0===this.heap.length)return null;const t=this.heap[0];return this.heap[0]=this.heap[this.heap.length-1],this.heap.pop(),this.heapifyDown(),t}peek(){return 0===this.heap.length?null:this.heap[0]}enqueue(t){this.heap.push(t),this.heapifyUp()}heapifyUp(){let t=this.heap.length-1;for(;this.hasParent(t)&&this.parent(t).f>this.heap[t].f;)this.swap(this.getParentIndex(t),t),t=this.getParentIndex(t)}heapifyDown(){let t=0;for(;this.hasLeftChild(t);){let e=this.getLeftChildIndex(t);if(this.hasRightChild(t)&&this.rightChild(t).f<this.leftChild(t).f&&(e=this.getRightChildIndex(t)),this.heap[t].f<this.heap[e].f)break;this.swap(t,e),t=e}}getTopN(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}},Jn=class extends Ln{getSolverName(){return"SingleHighDensityRouteSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;straightLineDistance;viaDiameter;traceThickness;obstacleMargin;layerCount;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;VIA_PENALTY_FACTOR=.3;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{},this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.obstacleRoutes=t.obstacleRoutes,this.A=t.A,this.B=t.B,this.viaDiameter=t.viaDiameter??.3,this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.layerCount=t.layerCount??2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length;const e=Math.ceil(5*(this.numRoutes+1));let n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;for(;n*s>e**2&&!(2*this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const o=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!o&&this.handleSimpleCases();const i={x:Math.round(t.A.x/(this.cellStep/2))*(this.cellStep/2),y:Math.round(t.A.y/(this.cellStep/2))*(this.cellStep/2)};this.initialNodeGridOffset={x:i.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:i.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.candidates=new qn([{...t.A,...i,z:t.A.z??0,g:0,h:0,f:0,parent:{...t.A,z:t.A.z??0,g:0,h:0,f:0,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this,n=t.z===e.z?[t,e]:[t,{...this.boundsCenter,z:this.A.z},{...this.boundsCenter,z:e.z},e];this.solvedPath={connectionName:this.connectionName,route:n,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:this.A.z===this.B.z?[]:[this.boundsCenter]}}get viaPenaltyDistance(){return this.cellStep+this.straightLineDistance*this.VIA_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e,n){if(e??=this.obstacleMargin,n&&t.parent){const n=this.getViasInNodePath(t.parent);for(const s of n)if(k(t,s)<this.viaDiameter/2+e)return!0}for(const s of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,s.connectionName);if(!o){const o=Kn(s);for(const s of o)if((n||s.z===t.z)&&X(t,s.A,s.B)<this.traceThickness+e)return!0}for(const n of s.vias)if(k(t,n)<this.viaDiameter/2+this.traceThickness/2+e)return!0}return!1}isNodeTooCloseToEdge(t,e){const n=e?this.viaDiameter/2+this.obstacleMargin/2:this.obstacleMargin/2,s=t.x<this.bounds.minX+n||t.x>this.bounds.maxX-n||t.y<this.bounds.minY+n||t.y>this.bounds.maxY-n;return!(s&&!e&&(k(t,this.B)<2*n||k(t,this.A)<2*n))&&s}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s)for(const s of Kn(n))if(s.z===t.z&&L(t,e,s.A,s.B))return!0}return!1}computeH(t){return k(t,this.B)+(t.z!==this.B.z?this.viaPenaltyDistance:0)}computeG(t){return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+k(t,t.parent)}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getNodeKey(t){return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}`}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;const c={...t,parent:t,x:Qn(t.x+r*this.cellStep,s,n),y:Qn(t.y+a*this.cellStep,i,o)},h=this.getNodeKey(c);this.exploredNodes.has(h)||(this.isNodeTooCloseToObstacle(c)?(this.debug_nodesTooCloseToObstacle.add(h),this.exploredNodes.add(h)):this.isNodeTooCloseToEdge(c,!1)?this.exploredNodes.add(h):this.doesPathToParentIntersectObstacle(c)?(this.debug_nodePathToParentIntersectsObstacle.add(h),this.exploredNodes.add(h)):(c.g=this.computeG(c),c.h=this.computeH(c),c.f=this.computeF(c.g,c.h),e.push(c)))}for(let n=0;n<this.layerCount;n++){if(n===t.z)continue;const s={...t,parent:t,z:n};this.exploredNodes.has(this.getNodeKey(s))||this.isNodeTooCloseToObstacle(s,this.viaDiameter/2+this.obstacleMargin/2,!0)||this.isNodeTooCloseToEdge(s,!0)||(s.g=this.computeG(s),s.h=this.computeH(s),s.f=this.computeF(s.g,s.h),e.push(s))}return e}getNodePath(t){const e=[];for(;t;)e.push(t),t=t.parent;return e}getViasInNodePath(t){const e=this.getNodePath(t),n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});return n}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});this.solvedPath={connectionName:this.connectionName,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:e.map(t=>({x:t.x,y:t.y,z:t.z})).concat([this.B]),vias:n}}computeProgress(t,e,n){n||(e+=this.viaPenaltyDistance);const s=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*s/(1-s)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e);const n=k(t,this.B);this.progress=this.computeProgress(t,n,t.z===this.B.z),n<=this.cellStep*Math.SQRT2&&t.z===this.B.z&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++){const o=n.route[s].z;t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:0===o?"rgba(255, 0, 0, 0.75)":"rgba(255, 128, 0, 0.25)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`})}}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e],[s,o,i]=n.split(",").map(Number);this.debug_nodesTooCloseToObstacle.has(n)||(this.debug_nodePathToParentIntersectsObstacle.has(n)||t.rects.push({center:{x:s+this.initialNodeGridOffset.x+i*this.cellStep/20,y:o+this.initialNodeGridOffset.y+i*this.cellStep/20},fill:0===i?`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`:`rgba(0,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:`Explored (z=${i})`}))}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x+e.z*this.cellStep/20,y:e.y+e.z*this.cellStep/20},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:`Next (z=${e.z})`})}for(const e of this.obstacleRoutes)for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:this.viaDiameter/2,fill:"rgba(255, 0, 0, 0.5)",label:"Via"});if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route"});for(const e of this.solvedPath.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"green",label:"Via"})}return t}};function Kn(t){const e=[];for(let n=0;n<t.route.length-1;n++)t.route[n].z===t.route[n+1].z&&e.push({z:t.route[n].z,A:t.route[n],B:t.route[n+1]});return e}function Qn(t,e,n){return Math.max(e,Math.min(t,n))}var ts=class extends Jn{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR=2;FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR=1;FUTURE_CONNECTION_PROXIMITY_VD=10;MISALIGNED_DIST_PENALTY_FACTOR=5;VIA_PENALTY_FACTOR_2=1;FLIP_TRACE_ALIGNMENT_DIRECTION=!1;constructor(t){super(t);for(const e in t.hyperParameters)this[e]=t.hyperParameters[e];const e=this.boundsSize.width/this.viaDiameter,n=Math.max(1,this.numRoutes);this.VIA_PENALTY_FACTOR=e/n*.3*this.VIA_PENALTY_FACTOR_2}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o)+(t.z!==o.z?this.viaPenaltyDistance:0);s<e&&(e=s,n=o)}return n}diminishCloseToGoal(t){const e=k(t,this.B);return 1-Math.exp(-e/this.straightLineDistance*5)}getFutureConnectionPenalty(t,e){let n=0;const s=this.getClosestFutureConnectionPoint(t),o=k(t,this.B);if(s){const i=k(t,s);if(o<=i)return 0;const r=i/(this.viaDiameter*this.FUTURE_CONNECTION_PROXIMITY_VD);n=(e?this.straightLineDistance*this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:this.straightLineDistance*this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR)*Math.exp(5*-r)}return n}computeH(t){const e=k(t,this.B)**1.6;this.straightLineDistance;return e+(t.z!==this.B.z?this.viaPenaltyDistance:0)+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}computeG(t){const e=Math.abs(t.x-t.parent.x),n=Math.abs(t.y-t.parent.y),s=Math.sqrt(e**2+n**2),o=t.z%2==0,i=this.FLIP_TRACE_ALIGNMENT_DIRECTION?o?e:n:o?n:e;return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+s+i*this.MISALIGNED_DIST_PENALTY_FACTOR+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}},es=class extends Ln{getSolverName(){return"IntraNodeRouteSolver"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;viaDiameter;traceWidth;activeSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??.3,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,x:n,y:o,z:i}of e.portPoints)s.set(t,[...s.get(t)??[],{x:n,y:o,z:i??0}]);this.unsolvedConnections=Array.from(s.entries().map(([t,e])=>({connectionName:t,points:e}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Gn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Gn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Zn(this.nodeWithPortPoints)}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o&&e.z===n.z)return;if(s&&o&&e.z!==n.z){const s={x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},o=[{x:e.x,y:e.y,z:e.z},{...s,z:e.z},{...s,z:n.z},{x:n.x,y:n.y,z:n.z}].filter((t,e,n)=>0===e||Math.abs(t.x-n[e-1].x)>1e-6||Math.abs(t.y-n[e-1].y)>1e-6||t.z!==n[e-1].z);return void this.solvedRoutes.push({connectionName:t.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:o,vias:[s]})}}const{connectionName:e,points:n}=t;this.activeSubSolver=new ts({connectionName:e,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ie(this.nodeWithPortPoints),A:{x:n[0].x,y:n[0].y,z:n[0].z},B:{x:n[n.length-1].x,y:n[n.length-1].y,z:n[n.length-1].z},obstacleRoutes:this.connMap?this.solvedRoutes.filter(t=>!this.connMap.areIdsConnected(t.connectionName,e)):this.solvedRoutes,futureConnections:this.unsolvedConnections,layerCount:this.nodeWithPortPoints.portPoints.reduce((t,e)=>Math.max(t,(e.z??0)+1),2),hyperParameters:this.hyperParameters,connMap:this.connMap,viaDiameter:this.viaDiameter,traceThickness:this.traceWidth})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,`layer: ${e.z}`].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let o=0;o<n.route.length-1;o++){const i=n.route[o],r=n.route[o+1];t.lines.push({points:[i,r],strokeColor:0===i.z?In(s,.2):In(s,.8),layer:`route-layer-${i.z}`,step:e,strokeWidth:n.traceThickness})}for(const o of n.vias)t.circles.push({center:{x:o.x,y:o.y},radius:n.viaDiameter/2,fill:In(s,.5),layer:"via",step:e})}}const e=Ie(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},ns=t=>Math.round(200*t)/200,ss=t=>"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t));Ne();var os=class extends es{getSolverName(){return"CachedIntraNodeRouteSolver"}cacheProvider;cacheHit=!1;hasAttemptedToUseCache=!1;initialUnsolvedConnections;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Me():t.cacheProvider,this.initialUnsolvedConnections=ss(this.unsolvedConnections),(this.solved||this.failed)&&this.cacheProvider&&!this.cacheHit&&this.saveToCacheSync()}_step(){if(!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync())return;const t=this.solved,e=this.failed;super._step(),!this.cacheProvider||this.cacheHit||!this.solved&&!this.failed||t||e||this.saveToCacheSync()}computeCacheKeyAndTransform(){const t=this.nodeWithPortPoints.center,e=this.initialUnsolvedConnections.map(({connectionName:e,points:n})=>({connectionName:e,points:n.map(n=>({connectionName:e,x:ns(n.x-t.x),y:ns(n.y-t.y),z:n.z??0}))})),n=Object.fromEntries(Object.entries(this.hyperParameters??{}).filter(([,t])=>void 0!==t).sort(([t],[e])=>t.localeCompare(e))),s=this.connMap?this.initialUnsolvedConnections.map(({connectionName:t})=>({connectionName:t,connectedIds:[...new Set(this.connMap.getIdsConnectedToNet(t)??[])].sort()})):void 0,o={node:{width:ns(this.nodeWithPortPoints.width),height:ns(this.nodeWithPortPoints.height),center:{x:ns(this.nodeWithPortPoints.center.x),y:ns(this.nodeWithPortPoints.center.y)},availableZ:this.nodeWithPortPoints.availableZ?[...this.nodeWithPortPoints.availableZ].sort():void 0},normalizedConnections:e,normalizedHyperParameters:n,minDistBetweenEnteringPoints:ns(this.minDistBetweenEnteringPoints),normalizedConnMap:s},i=`intranode-solver:${Hn(o)}`,r={};return this.cacheKey=i,this.cacheToSolveSpaceTransform=r,{cacheKey:i,cacheToSolveSpaceTransform:r}}applyCachedSolution(t){t.success?(this.solvedRoutes=ss(t.solvedRoutes),this.solved=!0,this.failed=!1):(this.solvedRoutes=[],this.failedSubSolvers=[],this.solved=!1,this.failed=!0,this.error=t.error??this.error),this.unsolvedConnections=[],this.activeSubSolver=null,this.cacheHit=!0,this.progress=1}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return!1;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return console.error("Error computing cache key:",t),!1}if(!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(null!=t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheProvider?.isSyncCache)return;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return void console.error("Error computing cache key during save:",t)}if(!this.cacheKey)return void console.error("Failed to compute cache key before saving.");const t=this.failed?{success:!1,error:this.error??void 0}:{success:!0,solvedRoutes:ss(this.solvedRoutes)};try{this.cacheProvider.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}},is=class extends Ln{getSolverName(){return"HyperParameterSupervisorSolver"}GREEDY_MULTIPLIER=1.2;MIN_SUBSTEPS=1;supervisedSolvers;winningSolver;getHyperParameterDefs(){throw new Error("Not implemented")}getCombinationDefs(){return null}getHyperParameterCombinations(t){t||(t=this.getHyperParameterDefs());const e=[];if(0===t.length)return[{}];const[n,...s]=t,o=this.getHyperParameterCombinations(s);return n.possibleValues.forEach(t=>{o.forEach(n=>{e.push({...n,...t})})}),e}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs()??[t.map(t=>t.name)];this.supervisedSolvers=[];for(const n of e){const e=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of e){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){throw new Error("Not implemented")}computeG(t){return t.iterations/t.MAX_ITERATIONS}computeH(t){return 1-(t.progress||0)}computeF(t,e){return t+e*this.GREEDY_MULTIPLIER}getSupervisedSolverWithBestFitness(){let t=1/0,e=null;for(const n of this.supervisedSolvers??[]){if(n.solver.solved)return n;if(n.solver.failed)continue;const s=n.f;s<t&&(t=s,e=n)}return e}getFailureMessage(){return`All solvers failed in hyper solver. Example failures: ${this.supervisedSolvers?.sort((t,e)=>e.f-t.f)?.slice(0,5).map(t=>t.solver.error).join(", ")}`}_step(){this.supervisedSolvers||this.initializeSolvers();const t=this.getSupervisedSolverWithBestFitness();if(!t)return this.failed=!0,void(this.error=this.getFailureMessage());for(let e=0;e<this.MIN_SUBSTEPS;e++)t.solver.step();this.activeSubSolver=t.solver,t.g=this.computeG(t.solver),t.h=this.computeH(t.solver),t.f=this.computeF(t.g,t.h),t.solver.solved&&(this.solved=!0,this.winningSolver=t.solver,this.onSolve?.(t))}onSolve(t){}visualize(){const t=this.getSupervisedSolverWithBestFitness();let e={lines:[],circles:[],points:[],rects:[]};return t&&(e=t.solver.visualize()),e}};function rs({A:t,B:e,C:n,D:s,E:o,F:i,radius:r,margin:a,subdivisions:c=0}){const h=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),l=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o),r=s/i,a=o/i,c=-a,h=r;return{midpoint:{x:(t.x+e.x)/2,y:(t.y+e.y)/2},A_Opp:{x:t.x-r*n,y:t.y-a*n},A_Right:{x:t.x+c*n,y:t.y+h*n},A_Left:{x:t.x-c*n,y:t.y-h*n},B_Opp:{x:e.x+r*n,y:e.y+a*n},B_Right:{x:e.x+c*n,y:e.y+h*n},B_Left:{x:e.x-c*n,y:e.y-h*n}}},d=(t,e)=>{const n=k(t,e.start),s=k(t,e.end),o=k(e.start,e.end);return Math.abs(n+s-o)<1e-4},u=(t,e)=>{const{start:n,end:s}=t,{start:o,end:i}=e;if(d(n,e)||d(s,e)||d(o,t)||d(i,t))return!0;const r=s.x-n.x,a=s.y-n.y,c=i.x-o.x,h=i.y-o.y,l=r*h-a*c;if(Math.abs(l)<1e-4)return!1;const u=o.x-n.x,p=o.y-n.y,f=(u*h-p*c)/l,m=(u*a-p*r)/l;return f>0&&f<1&&m>0&&m<1},p=(t,e)=>{const n=[];for(let e=0;e<t.length-1;e++)n.push({start:t[e],end:t[e+1]});const s=[];for(let t=0;t<e.length-1;t++)s.push({start:e[t],end:e[t+1]});for(const t of n)for(const e of s)if(u(t,e))return!0;return!1},f=t=>{let e=0;for(let n=1;n<t.length;n++){const s=t[n].x-t[n-1].x,o=t[n].y-t[n-1].y;e+=Math.sqrt(s*s+o*o)}return e},m=(t,e)=>{const{start:n,end:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(0===r)return{...n,t:0};const a=Math.max(0,Math.min(1,((e.x-n.x)*o+(e.y-n.y)*i)/r));return{x:n.x+a*o,y:n.y+a*i,t:a}},g=(e,n,s)=>{const o=m(e,n);if(k(o,n)>=s)return o;const i=o.x-n.x,r=o.y-n.y,a=Math.sqrt(i*i+r*r);if(0===a){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Math.sqrt(i*i+r*r);return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}}return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}},y=l(t,e,r),x=l(t,e,r+a),v=(t,e,n,s,o)=>{const i=t.points;if(i.length<2)return i;const a=n+s,c=[i[0]];for(let t=0;t<i.length-1;t++){const n={start:i[t],end:i[t+1]};if(X(e,n.start,n.end)<a){const t=m(n,e),s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);let h=null;if(i>1e-6)h={x:e.x+a*s/i,y:e.y+a*o/i};else{const t=n.end.x-n.start.x,s=n.end.y-n.start.y,o=Math.sqrt(t*t+s*s);o>1e-6&&(h={x:e.x+a*t/o,y:e.y+a*s/o})}h&&k(n.start,h)>r/10&&c.push(h)}k(c[c.length-1],n.end)>r/10&&c.push(n.end)}if(c.length>1){const t=[c[0]];for(let e=1;e<c.length;e++)k(t[t.length-1],c[e])>r/10&&t.push(c[e]);return t}return c},b=(()=>{const t=[[n,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.B_Right,y.A_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,s],[n,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,s],[s,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.A_Right,y.B_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,n],[s,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,n]],e=[];for(let n=0;n<t.length;n++){const s=t[n],o={start:s[0],end:s[1]},i={start:s[s.length-2],end:s[s.length-1]},r={start:s[3],end:s[4]};u(o,i)||u(o,r)||u(i,r)||e.push({index:n+1,path:s,length:f(s)})}if(0===e.length)return{index:0,path:[]};const o=e.sort((t,e)=>t.length-e.length)[0],i=[...o.path],r=i[0],a=k(r,i[2]),c=k(r,i[3]),l=a<c?2:3;(a<k(r,i[1])||c<k(r,i[1]))&&i.splice(1,l-1);const d=i[i.length-1],p=k(d,i[i.length-3]),m=k(d,i[i.length-4]),g=p<m?i.length-3:i.length-4;return(p<k(d,i[i.length-2])||m<k(d,i[i.length-2]))&&i.splice(g+1,i.length-g-2),{index:o.index,path:i,startsAt:i[0]===n?"C":"D",goesTo:i[i.length-1]===n?"C":"D"}})(),P=c>0?((n,s)=>{if(n.length<2)return n;const o=[n[0]];for(let i=0;i<n.length-1;i++){const a={start:n[i],end:n[i+1]},c={x:(a.start.x+a.end.x)/2,y:(a.start.y+a.end.y)/2},h=k(c,t),l=k(c,e);if((h<=r||l<=r)&&Math.abs(h-l)>1e-4){const n=m(a,t),i=m(a,e),c=k(n,t),h=k(i,e)<r,l=c<r?g(a,t,r):null,d=h?g(a,e,r):null;let u=[];if(k(a.start,a.end)>r/2&&s>0)for(let n=1;n<=s;n++){const o=n/(s+1),i={x:a.start.x+o*(a.end.x-a.start.x),y:a.start.y+o*(a.end.y-a.start.y),t:o,isSpecial:!1},c=k(i,t),h=k(i,e);c<r||h<r||(l&&Math.abs(i.t-l.t)<.1||d&&Math.abs(i.t-d.t)<.1||u.push(i))}if(l&&u.push(l),d&&u.push(d),u.sort((t,e)=>t.t-e.t),u.length>1){const t=[u[0]];for(let e=1;e<u.length;e++){const n=t[t.length-1],s=u[e];k(n,s)>r/10&&t.push(s)}u=t}u.forEach(t=>o.push(t))}o.push(n[i+1])}if(o.length>1){const t=[o[0]];for(let e=1;e<o.length;e++){const n=t[t.length-1],s=o[e];k(n,s)>r/10&&t.push(s)}return t}return o})(b.path,c):b.path;let S=(()=>{if(0===b.path.length)return null;const n=(()=>{const n=h(y.A_Right,y.B_Right),s=h(y.B_Left,y.A_Left);return[{startsAt:"E",goesTo:"B",points:[o,e]},{startsAt:"E",goesTo:"A",points:[o,t]},{startsAt:"F",goesTo:"B",points:[i,e]},{startsAt:"F",goesTo:"A",points:[i,t]},{startsAt:"E",goesTo:"B",points:[o,n,e]},{startsAt:"E",goesTo:"A",points:[o,n,t]},{startsAt:"F",goesTo:"B",points:[i,n,e]},{startsAt:"F",goesTo:"A",points:[i,n,t]},{startsAt:"E",goesTo:"B",points:[o,s,e]},{startsAt:"E",goesTo:"A",points:[o,s,t]},{startsAt:"F",goesTo:"B",points:[i,s,e]},{startsAt:"F",goesTo:"A",points:[i,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,n,e]},{startsAt:"F",goesTo:"B",points:[i,x.B_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,s,t]},{startsAt:"F",goesTo:"A",points:[i,x.A_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Left,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,x.B_Opp,x.B_Right,n,t]}].map((t,e)=>({...t,index:e}))})(),s=n.filter(t=>"E"===t.startsAt),r=n.filter(t=>"F"===t.startsAt),a=[],c=[];for(const t of s)if(!p(t.points,b.path)){a.push(t);break}for(const t of r)if(!p(t.points,b.path)){c.push(t);break}return 0===a.length||0===c.length?null:{line1:a[0],line2:c[0]}})();if(S){const n="A"===S.line1.goesTo?e:t,s="A"===S.line2.goesTo?e:t,o=v(S.line1,n,r,a),i=v(S.line2,s,r,a);S={line1:{...S.line1,points:o},line2:{...S.line2,points:i}}}return{jPair:S,optimalPath:{startsAt:b.startsAt,goesTo:b.goesTo,points:P}}}var as=class extends Ln{getSolverName(){return"TwoCrossingRoutesHighDensitySolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;escapeLayer=1;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const[e,n]=this.routes;if(!(e.startPort.z===e.endPort.z))return this.failed=!0,void(this.error="Route A must start and end on the same layer");if(!(n.startPort.z===n.endPort.z))return this.failed=!0,void(this.error="Route B must start and end on the same layer");if(!(e.startPort.z===n.startPort.z))return this.failed=!0,void(this.error="Both routes must be on the same layer");0===e.startPort.z?this.escapeLayer=1:this.escapeLayer=0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({startPort:{...s[0],z:s[0].z??0},endPort:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}doRoutesCross(t,e){return L(t.startPort,t.endPort,e.startPort,e.endPort)}calculateViaPositions(t,e){const n=this.bounds.maxX-this.bounds.minX,s=this.bounds.maxY-this.bounds.minY,o=this.bounds.minX,i=this.bounds.minY,r={width:n-2*this.obstacleMargin-this.viaDiameter,height:s-2*this.obstacleMargin-this.viaDiameter,x:o+this.obstacleMargin+this.viaDiameter/2,y:i+this.obstacleMargin+this.viaDiameter/2},a=this.viaDiameter+this.obstacleMargin,c=e.startPort,h=e.endPort,l=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}],d=(t,e)=>k(t,e),u=[];l.forEach((t,e)=>{d(t,c)>=a&&d(t,h)>=a&&u.push({...t,type:"corner",index:e})});const p=[{p1:l[0],p2:l[1]},{p1:l[1],p2:l[2]},{p1:l[2],p2:l[3]},{p1:l[3],p2:l[0]}];if([c,h].forEach((t,e)=>{p.forEach((n,s)=>{((t,e)=>{const n=t.x,s=t.y,o=t.r,i=e.p1.x,r=e.p1.y,a=e.p2.x,c=e.p2.y;if(Math.abs(a-i)<.001){const t=i,e=o*o-(t-n)**2;if(e<0)return[];if(Math.abs(e)<.001){const e=s;return e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const a=s+Math.sqrt(e),h=s-Math.sqrt(e),l=[];return a>=Math.min(r,c)&&a<=Math.max(r,c)&&l.push({x:t,y:a}),h>=Math.min(r,c)&&h<=Math.max(r,c)&&l.push({x:t,y:h}),l}const h=(c-r)/(a-i),l=r-h*i,d=1+h*h,u=2*(h*l-h*s-n),p=u*u-4*d*(n*n+(l-s)*(l-s)-o*o);if(p<0)return[];if(Math.abs(p)<.001){const t=-u/(2*d),e=h*t+l;return t>=Math.min(i,a)&&t<=Math.max(i,a)&&e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const f=(-u+Math.sqrt(p))/(2*d),m=(-u-Math.sqrt(p))/(2*d),g=h*f+l,y=h*m+l,x=[];return f>=Math.min(i,a)&&f<=Math.max(i,a)&&g>=Math.min(r,c)&&g<=Math.max(r,c)&&x.push({x:f,y:g}),m>=Math.min(i,a)&&m<=Math.max(i,a)&&y>=Math.min(r,c)&&y<=Math.max(r,c)&&x.push({x:m,y:y}),x})({...t,r:a},n).forEach(t=>{d(t,0===e?h:c)>=a&&u.push({...t,type:"intersection",circle:e,edge:s})})})}),u.length<2){const t=.8*a;if(l.forEach((e,n)=>{d(e,c)>=t&&d(e,h)>=t&&!u.some(t=>t.x===e.x&&t.y===e.y)&&u.push({...e,type:"relaxed_corner",index:n})}),u.length<2){const t=[...l].sort((t,e)=>{const n=Math.min(d(t,c),d(t,h));return Math.min(d(e,c),d(e,h))-n});for(const e of t)if(!u.some(t=>t.x===e.x&&t.y===e.y)&&(u.push({...e,type:"forced_corner"}),u.length>=2))break}}if(u.length<2)return null;let f=0,m=[u[0],u[u.length>1?1:0]];for(let t=0;t<u.length;t++)for(let e=t+1;e<u.length;e++){const n=d(u[t],u[e]);n>f&&(f=n,m=[u[t],u[e]])}let g={x:m[0].x,y:m[0].y},y={x:m[1].x,y:m[1].y};const x=k(g,t.startPort);return k(y,t.startPort)<x&&([g,y]=[y,g]),{via1:g,via2:y}}trySolveAOverB(t,e,n=!1){const s=n?this.calculateViaPositions(t,e):this.calculateViaPositions(e,t);if(!s)return!1;this.debugViaPositions.push(s);const{via1:o,via2:i}=this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(s));this.debugViaPositions.push({via1:o,via2:i});const{jPair:r,optimalPath:a}=rs({A:o,B:i,C:t.startPort,D:t.endPort,E:e.startPort,F:e.endPort,radius:this.viaDiameter/2+this.obstacleMargin+this.traceThickness/2*1.5,margin:2*this.obstacleMargin+this.traceThickness/2*1.5,subdivisions:1});if(!r)return!1;const c={connectionName:t.connectionName,route:a.points.map(e=>({x:e.x,y:e.y,z:t.startPort.z??0})),traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};r.line2.points.reverse();const h={connectionName:e.connectionName,route:[...r.line1.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0})),{...r.line1.points[r.line1.points.length-1],z:this.escapeLayer},{...r.line2.points[0],z:this.escapeLayer},...r.line2.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0}))],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[o,i]};return this.solvedRoutes.push(c,h),!0}pushViasFromEndpoints(t){const e={...t.via1},n={...t.via2},s=[this.routes[0].startPort,this.routes[0].endPort,this.routes[1].startPort,this.routes[1].endPort],o=this.getMinDistanceBetweenViaCenters(),i=this.viaDiameter/2+2*this.traceThickness+2*this.obstacleMargin;for(let t=0;t<10;t++){let r=!1,a=!1;const c=.9**t;for(const t of s){const s=k(e,t);if(s<i){const n=(i-s)*c,o=e.x-t.x,a=e.y-t.y,h=Math.sqrt(o*o+a*a);h>1e-6&&(e.x+=o/h*n,e.y+=a/h*n,r=!0)}const o=k(n,t);if(o<i){const e=(i-o)*c,s=n.x-t.x,r=n.y-t.y,h=Math.sqrt(s*s+r*r);h>1e-6&&(n.x+=s/h*e,n.y+=r/h*e,a=!0)}}const h=k(e,n);if(h<o){const t=(o-h)/2,s=n.x-e.x,i=n.y-e.y,c=Math.sqrt(s*s+i*i);c>1e-6?(e.x-=s/c*t,e.y-=i/c*t,n.x+=s/c*t,n.y+=i/c*t,r=!0,a=!0):(e.x-=t,n.x+=t,r=!0,a=!0)}if(!r&&!a)break}const r=k(e,n);if(r<o){const t=(o-r)/2,s=n.x-e.x,i=n.y-e.y,a=Math.sqrt(s*s+i*i);a>1e-6?(e.x-=s/a*t,e.y-=i/a*t,n.x+=s/a*t,n.y+=i/a*t):(e.x-=t,n.x+=t)}return{via1:e,via2:n}}getMinDistanceBetweenViaCenters(){return this.viaDiameter+this.traceThickness+2*this.obstacleMargin}moveViasAsCloseAsPossible(t){const{via1:e,via2:n}=t,s=this.getMinDistanceBetweenViaCenters(),o=k(e,n);if(o<=s)return t;const i=n.x-e.x,r=n.y-e.y,a=Math.sqrt(i*i+r*r),c=i/a,h=r/a,l=(e.x,n.x,e.y,n.y,(o-s)/2);return{via1:{x:e.x+c*l,y:e.y+h*l},via2:{x:n.x-c*l,y:n.y-h*l}}}handleRoutesDontCross(){const[t,e]=this.routes,n={connectionName:t.connectionName,route:[{x:t.startPort.x,y:t.startPort.y,z:t.startPort.z??0},{x:t.endPort.x,y:t.endPort.y,z:t.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]},s={connectionName:e.connectionName,route:[{x:e.startPort.x,y:e.startPort.y,z:e.startPort.z??0},{x:e.endPort.x,y:e.endPort.y,z:e.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};this.solvedRoutes.push(n,s),this.solved=!0}_step(){if(2!==this.routes.length)return void(this.failed=!0);const[t,e]=this.routes;this.doRoutesCross(t,e)?this.trySolveAOverB(t,e)||this.trySolveAOverB(e,t)||this.trySolveAOverB(t,e,!0)||this.trySolveAOverB(e,t,!0)?this.solved=!0:(this.failed=!0,this.error="All crossover strategies failed"):this.handleRoutesDontCross()}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)"});for(const[e,n]of[["Route A",this.routes[0]],["Route B",this.routes[1]]])t.points.push({x:n.startPort.x,y:n.startPort.y,label:`${e}\n${n.connectionName} start`,color:"orange"}),t.points.push({x:n.endPort.x,y:n.endPort.y,label:`${e}\n${n.connectionName} end`,color:"orange"}),t.lines.push({points:[n.startPort,n.endPort],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e}\n${n.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via1:n,via2:s}=this.debugViaPositions[e],o=["rgba(255, 165, 0, 0.3)","rgba(128, 0, 128, 0.3)"],i=o[e%o.length];t.circles.push({center:n,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via A (attempt ${e+1})`}),t.circles.push({center:s,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via B (attempt ${e+1})`});const r=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 1 Safety Margin (attempt ${e+1})`}),t.circles.push({center:s,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 2 Safety Margin (attempt ${e+1})`}),t.lines.push({points:[this.routes[e%2].startPort,n,s,this.routes[e%2].endPort],strokeColor:`${i.substring(0,i.lastIndexOf(","))}, 0.3)`,strokeDash:[5,5],label:`Potential Route (attempt ${e+1})`})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:1===o.z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`}),o._label&&t.points.push({x:o.x,y:o.y,label:o._label})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Solved Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},cs=({value:t,min:e,max:n})=>t>=e&&t<=n,hs=({value:t,target:e,epsilon:n})=>Math.abs(t-e)<=n,ls=({point:t,bounds:e,epsilon:n=1e-6})=>{if(![t.x,t.y,e.minX,e.maxX,e.minY,e.maxY].every(t=>(({value:t})=>Number.isFinite(t))({value:t})))return"outside";const s=function(t,e){return t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY?0:k(t,{x:D(t.x,e.minX,e.maxX),y:D(t.y,e.minY,e.maxY)})}(t,e);if(s>n)return"outside";const o=hs({value:t.x,target:e.minX,epsilon:n}),i=hs({value:t.x,target:e.maxX,epsilon:n}),r=hs({value:t.y,target:e.minY,epsilon:n}),a=hs({value:t.y,target:e.maxY,epsilon:n}),c=o||i,h=r||a;if(c&&h)return"on-boundary";const l=cs({value:t.y,min:e.minY,max:e.maxY}),d=cs({value:t.x,min:e.minX,max:e.maxX});return c&&l||h&&d?"on-boundary":"inside"};function ds(t,e,n,s,o){const i={x:(t.x+e.x+n.x)/3,y:(t.y+e.y+n.y)/3},r=(t,e)=>Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),a=i=>{const a=r(i,t),c=r(i,e),h=r(i,n),l=i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY;return a>=s&&c>=s&&h>=s&&l};if(a(i))return i;const c=(t,e,n)=>{const s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);return i<1e-10?{x:e.x+n,y:e.y}:{x:e.x+s/i*n,y:e.y+o/i*n}},h=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(i>2*n-1e-10||i<1e-10)return[];const a=i*i/(2*i),c=Math.sqrt(Math.max(0,n*n-a*a)),h=t.x+s*a/i,l=t.y+o*a/i,d={x:h+c*o/i,y:l-c*s/i},u={x:h-c*o/i,y:l+c*s/i},p=[],f=1e-6;return Math.abs(r(d,t)-n)<f&&Math.abs(r(d,e)-n)<f&&p.push(d),Math.abs(r(u,t)-n)<f&&Math.abs(r(u,e)-n)<f&&p.push(u),p},l=[c(i,t,s),c(i,e,s),c(i,n,s),...h(t,e,s),...h(e,n,s),...h(n,t,s)],d=l.filter(a);if(d.length>0){const t=d.filter(t=>!(t=>{const e=1e-6;return Math.abs(t.x-o.minX)<e||Math.abs(t.x-o.maxX)<e||Math.abs(t.y-o.minY)<e||Math.abs(t.y-o.maxY)<e})(t));if(t.length>0)return t.sort((t,e)=>r(t,i)-r(e,i)),t[0]}let u=null,p=1/0;for(let t=o.minX+1;t<o.maxX;t+=5)for(let e=o.minY+1;e<o.maxY;e+=5){const n={x:t,y:e};if(a(n)){const t=r(n,i);t<p&&(p=t,u=n)}}if(null!==u)return u;const f=[];for(let t=0;t<=100;t++){const e=t/100;f.push({x:o.minX+e*(o.maxX-o.minX),y:o.minY}),f.push({x:o.maxX,y:o.minY+e*(o.maxY-o.minY)}),f.push({x:o.maxX-e*(o.maxX-o.minX),y:o.maxY}),f.push({x:o.minX,y:o.maxY-e*(o.maxY-o.minY)})}const m=f.filter(a);if(m.length>0)return m.sort((t,e)=>r(t,i)-r(e,i)),m[0];let g=1/0,y={x:o.minX,y:o.minY};for(const i of[...l,...f])if(i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY){const o=Math.max(0,s-r(i,t))+Math.max(0,s-r(i,e))+Math.max(0,s-r(i,n));o<g&&(g=o,y=i)}return y}function us(t,e,n){const s=ps(e,t,n.center,n.radius),o=ps(t,e,n.center,n.radius),i=fs(s,e),r=fs(t,o),a=1e-6;let c;if(i>a&&r>a){c={x:(s.x+o.x)/2,y:(s.y+o.y)/2};const i=fs(s,c),r=fs(o,c);if(Math.abs(i-r)>.5*Math.min(i,r)){const n=fs(t,s),i=fs(e,o),r=n+i;if(r>a){const t=i/r,e=n/r;c={x:s.x*t+o.x*e,y:s.y*t+o.y*e}}}const h=fs(c,n.center);if(h<1.05*n.radius){const t={x:(c.x-n.center.x)/h,y:(c.y-n.center.y)/h};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}}else{const s={x:(t.x+e.x)/2,y:(t.y+e.y)/2},o=fs(s,n.center);if(o<1.1*n.radius){const t={x:(s.x-n.center.x)/o,y:(s.y-n.center.y)/o};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}else c=s}return{B:s,D:o,E:c}}function ps(t,e,n,s){const o=[n.x-t.x,n.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);if(i<=s){if(i<1e-8){const o=[e.x-t.x,e.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);return i<1e-8?{x:n.x+s,y:n.y}:{x:n.x+o[0]/i*s,y:n.y+o[1]/i*s}}const r=[o[0]/i,o[1]/i];return{x:n.x-r[0]*s,y:n.y-r[1]*s}}const r=[e.x-t.x,e.y-t.y],a=Math.sqrt(i*i-s*s),c=[o[0]/i,o[1]/i],h=[-c[1],c[0]],l=[c[1],-c[0]],d=r[0]*h[0]+r[1]*h[1]>r[0]*l[0]+r[1]*l[1]?h:l,u=s/i,p=a/i,f=[c[0]*p+d[0]*u,c[1]*p+d[1]*u];return{x:t.x+a*f[0],y:t.y+a*f[1]}}function fs(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var ms=1e-9;function gs(t,e,n,s="cw"){const o=ys(t,n),i=ys(e,n);return Math.abs(i-o)<ms?{left:0,top:0,right:0,bottom:0}:function(t,e,n,s){const o=n.maxX-n.minX,i=n.maxY-n.minY;if(o<ms&&i<ms)return{left:0,top:0,right:0,bottom:0};const r=2*(o+i);if(r<ms)return{left:0,top:0,right:0,bottom:0};const a=o/r*(2*Math.PI),c=(o+i)/r*(2*Math.PI),h=(o+o+i)/r*(2*Math.PI),l=2*Math.PI,d=[{name:"top",start:0,end:a,length:o},{name:"right",start:a,end:c,length:i},{name:"bottom",start:c,end:h,length:o},{name:"left",start:h,end:l,length:i}],u={left:0,top:0,right:0,bottom:0},p=(t,e,n,s,o)=>{const i=e>2*Math.PI-ms?2*Math.PI:e;if(i<=t+ms)return 0;if(o){const e=Math.max(t,n),o=Math.min(i,2*Math.PI),r=Math.max(0,o-e),a=Math.max(t,0),c=Math.min(i,s);return r+Math.max(0,c-a)}{const e=Math.max(t,n),o=Math.min(i,s);return Math.max(0,o-e)}};for(const n of d){const o=n.end-n.start;if(o<ms||n.length<ms)continue;let i=0;if("cw"===s){const s=t>e+ms;i=p(n.start,n.end,t,e,s)}else{const s=e>t+ms;i=p(n.start,n.end,e,t,s)}if(i>ms){const t=i/o;u[n.name]+=Math.max(0,Number.isFinite(t)?t:0)}}for(const t in u)u[t]=Math.max(0,Math.min(1,u[t]));return u}(o,i,n,s)}function ys(t,e){const n=e.maxX-e.minX,s=e.maxY-e.minY;if(n<ms&&s<ms)return 0;const o=2*(n+s);if(o<ms)return 0;let i=0;if(Math.abs(t.y-e.maxY)<ms&&t.x>=e.minX-ms&&t.x<=e.maxX+ms)i=Math.max(0,Math.min(n,t.x-e.minX));else if(Math.abs(t.x-e.maxX)<ms&&t.y>=e.minY-ms&&t.y<=e.maxY+ms)i=n+Math.max(0,Math.min(s,e.maxY-t.y));else if(Math.abs(t.y-e.minY)<ms&&t.x>=e.minX-ms&&t.x<=e.maxX+ms)i=n+s+Math.max(0,Math.min(n,e.maxX-t.x));else{if(!(Math.abs(t.x-e.minX)<ms&&t.y>=e.minY-ms&&t.y<=e.maxY+ms))throw new Error(`Point (${t.x}, ${t.y}) does not lie on the boundary defined by ${JSON.stringify(e)}`);i=n+s+n+Math.max(0,Math.min(s,t.y-e.minY))}return i=Math.max(0,Math.min(o,i)),o>ms?i/o*(2*Math.PI):0}function xs(t,e,n,s){return function({angleA:t,angleB:e,angleC:n}){const s=Math.cos(t),o=Math.sin(t),i=Math.cos(e),r=Math.sin(e),a=Math.cos(n);return(i-s)*(Math.sin(n)-o)-(r-o)*(a-s)<0?"ccw":"cw"}({angleA:ys(t,s),angleB:ys(e,s),angleC:ys(n,s)})}var vs=class extends Ln{getSolverName(){return"SingleTransitionCrossingRouteSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const e=this.routes.flatMap(t=>[t.A,t.B]).map(t=>this.getPortPointBoundsPosition(t));if(e.includes("outside"))return this.failed=!0,void(this.error="Invalid route input: SingleTransitionCrossingRouteSolver received port point(s) outside node bounds");if(e.includes("inside"))return void(this.failed=!0);const[n,s]=this.routes,o=n.A.z!==n.B.z,i=s.A.z!==s.B.z;return o&&i||!o&&!i?(this.failed=!0,void(this.error="Exactly one route must have a layer transition")):void 0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0],z:s[0].z??0},B:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}getPortPointBoundsPosition(t,e=1e-6){return ls({point:t,bounds:this.bounds,epsilon:e})}doRoutesCross(t,e){return L(t.A,t.B,e.A,e.B)}calculateViaPosition(t,e){const n=e.A.z,s=t.A.z!==n?t.A:t.B,o=2*this.obstacleMargin+this.viaDiameter/2+this.traceThickness,i=this.obstacleMargin+this.viaDiameter/2,r=e.A,a=s,c=e.B,h=xs(r,a,c,this.bounds),l=function(t,e,n,s,o){const i=gs(t,e,s,o),r=gs(e,n,s,o),a={left:Math.min(1,i.left+r.left),top:Math.min(1,i.top+r.top),right:Math.min(1,i.right+r.right),bottom:Math.min(1,i.bottom+r.bottom)};for(const t in a)Math.abs(a[t])<ms&&(a[t]=0);return a}(r,a,c,this.bounds,h),d={minX:this.bounds.minX+(l.left>.5?o:i),minY:this.bounds.minY+(l.bottom>.5?o:i),maxX:this.bounds.maxX-(l.right>.5?o:i),maxY:this.bounds.maxY-(l.top>.5?o:i)};return d.maxY<d.minY&&(d.minY=(d.minY+d.maxY)/2,d.maxY=d.minY),d.maxX<d.minX&&(d.minX=(d.minX+d.maxX)/2,d.maxX=d.minX),ds(r,a,c,o,d)}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z??0},{x:n.x,y:n.y,z:t.z??0},{x:n.x,y:n.y,z:e.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}createFlatRoute(t,e,n,s,o,i){s.z,t.z;const r=this.viaDiameter/2+this.traceThickness/2+this.obstacleMargin,a=((t,e,n,s)=>{const o=n.x-t.x,i=n.y-t.y;return((t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}))({x:t.x+o*e,y:t.y+i*e},{x:n.x-o*s,y:n.y-i*s})})(n,this.viaDiameter,s.z!==t.z?s:o,this.traceThickness),c={center:{x:n.x,y:n.y},radius:r},h=us(t,a,c).E,l=us(a,e,c).E,d=us(t,h,c).E,u=us(h,a,c).E,p=us(a,l,c).E,f=us(l,e,c).E,m=us(u,p,c).E;return{connectionName:i,route:[{x:t.x,y:t.y,z:t.z??0},{x:d.x,y:d.y,z:t.z??0},{x:h.x,y:h.y,z:t.z??0},{x:u.x,y:u.y,z:t.z??0},{x:m.x,y:m.y,z:t.z??0},{x:p.x,y:p.y,z:t.z??0},{x:l.x,y:l.y,z:t.z??0},{x:f.x,y:f.y,z:t.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]}}trySolve(){const[t,e]=this.routes,n=t.A.z!==t.B.z,s=n?t:e,o=n?e:t,i=this.calculateViaPosition(s,o);if(!i)return!1;this.debugViaPositions.push({via:i});const r=this.createTransitionRoute(s.A,s.B,i,s.connectionName),a=this.createFlatRoute(o.A,o.B,i,s.A,s.B,o.connectionName);return this.solvedRoutes.push(r,a),!0}_step(){if(!this.doRoutesCross(this.routes[0],this.routes[1]))return this.failed=!0,void(this.error="Can only solve routes that have a single transition crossing");this.trySolve()?this.solved=!0:(this.failed=!0,this.error="Failed to find a valid via position and route path")}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"});for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via:n}=this.debugViaPositions[e];t.circles.push({center:n,radius:this.viaDiameter/2,fill:"rgba(255, 165, 0, 0.7)",stroke:"rgba(0, 0, 0, 0.5)",label:`Computed Via (attempt ${e+1})`});const s=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:s,stroke:"rgba(255, 165, 0, 0.7)",fill:"rgba(0, 0, 0, 0)",label:"Safety Margin"})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},bs=class extends Ln{getSolverName(){return"SingleTransitionIntraNodeSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),1!==this.routes.length)return this.failed=!0,void(this.error=`Expected 1 route, but got ${this.routes.length}`);const e=this.routes[0];if(void 0===e.A.z||void 0===e.B.z)return this.failed=!0,void(this.error="Route points should have predefined z values");if(e.A.z===e.B.z)return this.failed=!0,void(this.error="Only one route provided, but it has no transition");const n=this.viaDiameter/2+this.obstacleMargin,s={x:D((e.A.x+e.B.x)/2,this.bounds.minX+n,this.bounds.maxX-n),y:D((e.A.y+e.B.y)/2,this.bounds.minY+n,this.bounds.maxY-n)};this.solvedRoutes.push(this.createTransitionRoute(e.A,e.B,s,e.connectionName)),this.solved=!0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e).push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0]},B:{...s[1]},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z},{x:n.x,y:n.y,z:t.z},{x:n.x,y:n.y,z:e.z},{x:e.x,y:e.y,z:e.z}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}_step(){this.solved=!0}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"}),this.routes.length>0)for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s="rgba(0, 255, 0, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}},Ps=(t,e)=>{const n={};return t.portPoints.forEach((e,s)=>{n[e.connectionName]=`hsl(${360*s/t.portPoints.length}, 100%, 50%)`}),n},Ss=class extends Ln{getSolverName(){return"ViaPossibilitiesSolver2"}bounds;maxViaCount;portPairMap;colorMap;nodeWidth;availableZ;hyperParameters;VIA_INTERSECTION_BUFFER_DISTANCE=.05;PLACEHOLDER_WALL_BUFFER_DISTANCE=.1;NEW_HEAD_WALL_BUFFER_DISTANCE=.05;viaDiameter;unprocessedConnections;completedPaths=new Map;placeholderPaths=new Map;currentHead;currentConnectionName;currentPath;currentViaCount;constructor({nodeWithPortPoints:t,colorMap:e,hyperParameters:n,viaDiameter:s}){super(),this.MAX_ITERATIONS=1e5,this.colorMap=e??Ps(t),this.maxViaCount=5,this.bounds=Ie(t),this.nodeWidth=this.bounds.maxX-this.bounds.minX,this.portPairMap=(t=>{const e=new Map;return t.portPoints.forEach(t=>{e.has(t.connectionName)?e.get(t.connectionName).end=t:e.set(t.connectionName,{start:t,end:null,connectionName:t.connectionName})}),e})(t),this.stats.solutionsFound=0,this.availableZ=t.availableZ??[0,1],this.hyperParameters=n??{SHUFFLE_SEED:0},this.viaDiameter=s??.3,this.unprocessedConnections=Array.from(this.portPairMap.keys()).sort(),n?.SHUFFLE_SEED&&(this.unprocessedConnections=Gn(this.unprocessedConnections,n.SHUFFLE_SEED));for(const[t,{start:e,end:n}]of this.portPairMap.entries())if(e.z===n.z){const s=Math.abs(e.x-n.x)<1e-9,o=Math.abs(e.y-n.y)<1e-9;s||o?this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),this._padByPlaceholderWallBuffer(n),n]):this.placeholderPaths.set(t,[e,n])}else{const s=(e.x+n.x)/2,o=(e.y+n.y)/2,i=this._padByPlaceholderWallBuffer({x:s,y:o,z:e.z}),r=this._padByPlaceholderWallBuffer({x:s,y:o,z:n.z});this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),i,r,this._padByPlaceholderWallBuffer(n),n])}this.currentConnectionName=this.unprocessedConnections.pop();const o=this.portPairMap.get(this.currentConnectionName).start;this.currentHead=this._padByNewHeadWallBuffer(o),this.currentPath=[o,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}_padByNewHeadWallBuffer(t){return{x:D(t.x,this.bounds.minX+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.NEW_HEAD_WALL_BUFFER_DISTANCE),y:D(t.y,this.bounds.minY+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.NEW_HEAD_WALL_BUFFER_DISTANCE),z:t.z}}_padByPlaceholderWallBuffer(t){return{x:D(t.x,this.bounds.minX+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),y:D(t.y,this.bounds.minY+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),z:t.z}}_step(){if(this.solved)return;const t=this.portPairMap.get(this.currentConnectionName).end,e=[this.currentHead,t];let n=null,s=null;const o=t=>{for(const o of t.values())for(let t=0;t<o.length-1;t++){const i=[o[t],o[t+1]];if(i[0].x===i[1].x&&i[0].y===i[1].y)continue;if(i[0].z!==this.currentHead.z)continue;const r=$(e[0],e[1],i[0],i[1]);if(r){const t=k(this.currentHead,r);if(t<1e-6)continue;(!n||t<n.dist)&&(n={point:r,dist:t},s=i[0].z)}}};o(this.completedPaths),o(this.placeholderPaths);const i=this.currentHead.z!==t.z;if((n||i)&&(this.currentViaCount++,this.currentViaCount>=this.maxViaCount))return this.failed=!0,void(this.error=`Exceeded max via count of ${this.maxViaCount}`);if(n){let t;const e=n.dist;if(e<=this.VIA_INTERSECTION_BUFFER_DISTANCE+1e-6)t=j(this.currentHead,n.point);else{const s=n.point,o=s.x-this.currentHead.x,i=s.y-this.currentHead.y,r=(e-this.VIA_INTERSECTION_BUFFER_DISTANCE)/e;t={x:this.currentHead.x+o*r,y:this.currentHead.y+i*r}}const o=this.availableZ.find(t=>t!==s);if(void 0===o)return this.error="Could not determine next Z level for via placement!",void(this.failed=!0);const i={...t,z:this.currentHead.z},r={...t,z:o};this.currentPath.push(i,r),this.currentHead=r}else if(i){let e;const n=k(this.currentHead,t);if(n<this.VIA_INTERSECTION_BUFFER_DISTANCE)e=j(this.currentHead,t);else{const s=t.x-this.currentHead.x,o=t.y-this.currentHead.y,i=(n-this.VIA_INTERSECTION_BUFFER_DISTANCE)/n;e={x:this.currentHead.x+s*i,y:this.currentHead.y+o*i}}const s=t.z,o={...e,z:this.currentHead.z},i={...e,z:s};this.currentPath.push(o,i),this.currentHead=i}else if(this.currentPath.push(t),this.completedPaths.set(this.currentConnectionName,this.currentPath),0===this.unprocessedConnections.length)this.solved=!0,this.stats.solutionsFound=1;else{this.currentConnectionName=this.unprocessedConnections.pop();const{start:t}=this.portPairMap.get(this.currentConnectionName);this.currentHead=this._padByNewHeadWallBuffer(t),this.currentPath=[t,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Via Possibilities Solver State",coordinateSystem:"cartesian"},e=this.colorMap;t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray",strokeWidth:.01});for(const[e,{start:n,end:s}]of this.portPairMap.entries()){const o=this.colorMap[e]??"black";t.points.push({x:n.x,y:n.y,color:o,label:`Port: ${e} Start (z${n.z})`}),t.points.push({x:s.x,y:s.y,color:o,label:`Port: ${e} End (z${s.z})`})}const n=(n,s)=>{for(const[o,i]of n.entries()){const n=e[o]??"black";for(let e=0;e<i.length-1;e++){const r=i[e],a=i[e+1];r.x===a.x&&r.y===a.y&&r.z!==a.z?t.circles.push({center:{x:r.x,y:r.y},radius:this.viaDiameter/2,fill:In(n,.5),label:`${s}: ${o} Via (z${r.z}->z${a.z})`}):t.lines.push({points:[r,a],strokeColor:In(n,.5),strokeDash:0===r.z?void 0:[.1,.1],strokeWidth:.1,label:`${s}: ${o} (z${r.z})`})}}};if(n(this.placeholderPaths,"Placeholder"),n(this.completedPaths,"Completed"),this.currentPath&&this.currentPath.length>0){const n=e[this.currentConnectionName]??"orange";for(let e=0;e<this.currentPath.length-1;e++){const s=this.currentPath[e],o=this.currentPath[e+1];s.x===o.x&&s.y===o.y&&s.z!==o.z?t.circles.push({center:{x:s.x,y:s.y},radius:this.viaDiameter/2,fill:In(n,.5),label:`Current: ${this.currentConnectionName} Via (z${s.z}->z${o.z})`}):t.lines.push({points:[s,o],strokeColor:In(n,.5),strokeWidth:.15,strokeDash:"2,2",label:`Current: ${this.currentConnectionName} (z${s.z})`})}t.points.push({x:this.currentHead.x,y:this.currentHead.y,color:"green",label:`Current Head: ${this.currentConnectionName} (z${this.currentHead.z})`})}return t}},Ms=t=>Math.round(1e4*t),Ns=t=>{let e=0,n=[];const s=[];for(const e of t.portPoints){if(n.some(t=>t.connectionName===e.connectionName))continue;if(s.some(t=>t.connectionName===e.connectionName))continue;const o={connectionName:e.connectionName,z:e.z,points:[{x:Ms(e.x),y:Ms(e.y),z:e.z}]};for(const n of t.portPoints)e.connectionName===n.connectionName&&(e.x===n.x&&e.y===n.y||o.points.push({x:Ms(n.x),y:Ms(n.y),z:n.z}));o.points.some(t=>t.z!==o.z)?s.push(o):n.push(o)}n=n.filter(t=>t.points.length>1);for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];o.z===i.z&&L(o.points[0],o.points[1],i.points[0],i.points[1])&&e++}let o=0;for(let t=0;t<s.length;t++)for(let e=t+1;e<s.length;e++){const n=s[t],i=s[e];L(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:s.length,numTransitionPairCrossings:o}};var Is=t=>{const{start:e,end:n,segmentsPerPolyline:s,viaPositions:o,viaCount:i,availableZ:r}=t,a=function(t,e){const n=new Array(t).fill(0);if(0===e)return n;if(e===t)return n.fill(1);if(e<=t/2){const s=Math.floor(t/e),o=Math.floor((t-(s*(e-1)+1))/2);for(let t=0;t<e;t++)n[o+t*s]=1}else{const s=t-e,o=Math.floor(t/s),i=Math.floor((t-(o*(s-1)+1))/2);n.fill(1);for(let t=0;t<s;t++)n[i+t*o]=0}return n}(s,i),c=a.map(()=>null);let h=0,l=e.z1;const d=r.indexOf(e.z1);for(let t=0;t<a.length;t++)if(1===a[t]){const e=r[(d+h+1)%r.length];c[t]={...o[h],z1:l,z2:e},l=e,h++}let u=e;for(let t=0;t<c.length;t++){if(c[t]){u=c[t];continue}let e=n,s=c.length;for(let n=t+1;n<c.length;n++)if(c[n]){e=c[n],s=n;break}const o=s-t,i=e.x-u.x,r=e.y-u.y;for(let e=1/(o+1),n=0;t+n!==s;e+=1/(o+1),n++)c[t+n]={x:u.x+i*e,y:u.y+r*e,z1:u.z2,z2:u.z2}}return c},_s=1e-9;function Cs(t,e){return Math.abs(t-e)<_s}function Ts(t){return`${Math.round(t.x/_s)}:${Math.round(t.y/_s)}`}function Es(t,e,n,s){return t*s-e*n}function ws(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Es(o.x,o.y,i.x,i.y),a={x:n.x-t.x,y:n.y-t.y};if(Cs(r,0))return null;const c=Es(a.x,a.y,i.x,i.y)/r,h=Es(a.x,a.y,o.x,o.y)/r;return c>=-1e-9&&c<=1+_s&&h>=-1e-9&&h<=1+_s?{x:t.x+c*o.x,y:t.y+c*o.y}:null}function Rs(t,e,n){return Cs(Math.hypot(t.x-e.x,t.y-e.y)+Math.hypot(t.x-n.x,t.y-n.y),Math.hypot(e.x-n.x,e.y-n.y))}function Os(t,e){const n=[],s=new Map;for(const e of t){const t=[e.start,...e.mPoints,e.end];for(let o=0;o<t.length-1;o++){const i=t[o],r=t[o+1],a=i.z2;if(n.push({start:{x:i.x,y:i.y},end:{x:r.x,y:r.y},connectionName:e.connectionName,layer:a}),i.z1!==i.z2){const t=Ts(i);s.has(t)||s.set(t,{point:i,connectionName:e.connectionName})}}const o=t[t.length-1];if(o.z1!==o.z2){const t=Ts(o);s.has(t)||s.set(t,{point:o,connectionName:e.connectionName})}}const o=[{start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.maxY},end:{x:e.minX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.minX,y:e.maxY},end:{x:e.minX,y:e.minY},connectionName:null,layer:0}];n.push(...o);const i=new Map;let r=0;function a(t,e){const n=Ts(t);let o=i.get(n);if(!o){const e=s.has(n);o={id:r++,x:t.x,y:t.y,isVia:e,connectionNames:new Set,outgoingEdges:[]},i.set(n,o),e&&s.get(n)&&o.connectionNames.add(s.get(n).connectionName)}return e&&o.connectionNames.add(e),o}for(const t of n)a(t.start,t.connectionName),a(t.end,t.connectionName);const c=new Map;for(const t of n)c.set(t,[]);for(let t=0;t<n.length;t++)for(let e=t+1;e<n.length;e++){if(n[t].layer!==n[e].layer)continue;const s=ws(n[t].start,n[t].end,n[e].start,n[e].end);s&&(a(s),Rs(s,n[t].start,n[t].end)&&c.get(n[t]).push(s),Rs(s,n[e].start,n[e].end)&&c.get(n[e]).push(s))}const h=[];let l=0;for(const t of n){const e=[t.start,...c.get(t),t.end];e.sort((e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y;return Math.abs(s)>Math.abs(o)?(e.x-t.start.x)/s-(n.x-t.start.x)/s:Math.abs(o)<_s?0:(e.y-t.start.y)/o-(n.y-t.start.y)/o});const n=[];if(e.length>0){n.push(e[0]);for(let t=1;t<e.length;t++)Cs(e[t].x,e[t-1].x)&&Cs(e[t].y,e[t-1].y)||n.push(e[t])}for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1],i=a(s,t.connectionName),r=a(o,t.connectionName);if(i===r)continue;const c={id:l++,origin:i,twin:null,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1},d={id:l++,origin:r,twin:c,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1};c.twin=d,h.push(c,d),i.outgoingEdges.push(c),r.outgoingEdges.push(d)}}for(const t of i.values()){t.outgoingEdges.sort((e,n)=>{const s=e.twin.origin,o=n.twin.origin;return Math.atan2(s.y-t.y,s.x-t.x)-Math.atan2(o.y-t.y,o.x-t.x)});const e=t.outgoingEdges.length;for(let n=0;n<e;n++){const s=t.outgoingEdges[n],o=t.outgoingEdges[(n-1+e)%e];s.twin&&(s.twin.next=o)}}const d=[];let u=0,p=null,f=-1/0;for(const t of h){if(t.visited)continue;const e={id:u++,outerComponent:t,innerComponents:[],isOuterFace:!1};d.push(e);let n=t;const s=[],o=[],i=new Set;let r=0;do{if(!n||n.visited){console.warn("Face traversal encountered visited edge or null, breaking loop.",e.id),s.length=0;break}n.visited=!0,n.face=e,s.push(n),o.push(n.origin),null!==n.connectionName&&i.add(n.connectionName);const t=n.origin,a=n.twin.origin;r+=t.x*a.y-a.x*t.y,n=n.next}while(n!==t&&null!==n);if(n===t){if(r=.5*Math.abs(r),r>f&&(f=r,p&&(p.isOuterFace=!1),p=e,e.isOuterFace=!0),!e.isOuterFace&&s.length>0){if([...i].filter(t=>null!==t).length>1){let t=!1;for(const e of o)if(e.isVia){t=!0;break}if(!t)return!0}}}else console.warn(`Face ${e.id} did not close properly.`),d.pop(),u--}return!1}var As=t=>{if(0===t.length)return[[]];const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=[...t.slice(0,n),...t.slice(n+1)],i=As(o);for(const t of i)e.push([s,...t])}return e},zs=1e-9;function Ds(t,e,n=1e-9){return Math.abs(t-e)<n}function Ls(t,e,n,s){return t*s-e*n}function Fs(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Ls(o.x,o.y,i.x,i.y);if(Ds(r,0))return null;const a={x:n.x-t.x,y:n.y-t.y},c=Ls(a.x,a.y,i.x,i.y)/r,h=Ls(a.x,a.y,o.x,o.y)/r;return c<-1e-9||c>1+zs||h<-1e-9||h>1+zs?null:{x:t.x+c*o.x,y:t.y+c*o.y}}function Ys(t){let e=0;for(let n=0,s=t.length;n<s;++n){const o=(n+1)%s;e+=t[n].x*t[o].y-t[o].x*t[n].y}return.5*e}function Xs(t){let e=0,n=0,s=0;for(let o=0,i=t.length;o<i;++o){const r=(o+1)%i,a=t[o].x*t[r].y-t[r].x*t[o].y;e+=a,n+=(t[o].x+t[r].x)*a,s+=(t[o].y+t[r].y)*a}return e*=.5,Ds(e,0)?null:(n/=6*e,s/=6*e,{x:n,y:s})}var ks=class{x;y;out;connectionNames;constructor(t,e){this.x=t,this.y=e,this.out=[],this.connectionNames=new Set}},$s=class{orig;dest;twin;next;visited;constructor(t,e){this.orig=t,this.dest=e,this.twin=null,this.next=null,this.visited=!1}};function Bs(t,e){const n=[...e,...[{start:{x:t.minX,y:t.minY},end:{x:t.maxX,y:t.minY}},{start:{x:t.maxX,y:t.minY},end:{x:t.maxX,y:t.maxY}},{start:{x:t.maxX,y:t.maxY},end:{x:t.minX,y:t.maxY}},{start:{x:t.minX,y:t.maxY},end:{x:t.minX,y:t.minY}}]],s=n.map(()=>[]);for(let t=0;t<n.length;++t){const e=n[t];s[t].push(e.start,e.end)}for(let t=0;t<n.length;++t)for(let e=t+1;e<n.length;++e){const o=Fs(n[t].start,n[t].end,n[e].start,n[e].end);o&&(s[t].push(o),s[e].push(o))}const o=new Map,i=[];function r(t){const e=function(t,e=1e-9){return`${Math.round(t.x/e)}:${Math.round(t.y/e)}`}(t);if(!o.has(e)){const n=i.length;return o.set(e,n),i.push(new ks(t.x,t.y)),n}return o.get(e)}const a=[];for(let t=0;t<n.length;++t){const e=n[t],o=s[t].slice();o.sort((t,n)=>{const s=e.end.x-e.start.x,o=e.end.y-e.start.y;return(Ds(Math.abs(s),0)?(t.y-e.start.y)/o:(t.x-e.start.x)/s)-(Ds(Math.abs(s),0)?(n.y-e.start.y)/o:(n.x-e.start.x)/s)});for(let t=0;t<o.length-1;++t){const n=o[t],s=o[t+1],c=r(n),h=r(s);c!==h&&(a.push([c,h]),e.connectionName&&(i[c].connectionNames.add(e.connectionName),i[h].connectionNames.add(e.connectionName)))}}const c=[];for(const[t,e]of a){const n=new $s(t,e),s=new $s(e,t);n.twin=c.length+1,s.twin=c.length;const o=c.length;c.push(n,s),i[t].out.push(o),i[e].out.push(o+1)}for(let t=0;t<i.length;++t){const e=i[t];e.out.sort((t,n)=>{const s=c[t],o=c[n],r=i[s.dest],a=i[o.dest];return Math.atan2(r.y-e.y,r.x-e.x)-Math.atan2(a.y-e.y,a.x-e.x)});const n=e.out.length;for(let t=0;t<n;++t){const s=e.out[t],o=e.out[(t-1+n)%n],i=c[s];null!==i.twin&&(c[i.twin].next=o)}}const h=[],l=[];for(let t=0;t<c.length;++t){if(c[t].visited)continue;let e=t;const n=[],s=[];do{if(null===e)break;const t=c[e];t.visited=!0,n.push(i[t.orig]),s.push(e),e=t.next}while(null!==e&&e!==t&&!c[e].visited);if(n.length<3)continue;if(Ys(n)>zs){const t=Xs(n);t&&(h.push(t),l.push({vertices:n.map(t=>({x:t.x,y:t.y,connectionNames:t.connectionNames.size>0?t.connectionNames:void 0})),centroid:t}))}}return{centroids:h,faces:l,allVertices:i}}function js(t,e){if(t>e)throw new Error("oneCount cannot be greater than length");if(t<0||e<0)throw new Error("oneCount and length must be non-negative");const n=[];return function t(s,o,i){i!==e?(s[i]=0,t(s,o,i+1),o>0&&(s[i]=1,t(s,o-1,i+1))):0===o&&n.push([...s])}(Array(e).fill(0),t,0),n}var Ws=class extends Ln{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver"}nodeWithPortPoints;colorMap;hyperParameters;connMap;candidates;bounds;solvedRoutes=[];unsolvedConnections=[];SEGMENTS_PER_POLYLINE;cellSize;MAX_CANDIDATES=5e4;viaDiameter=.3;obstacleMargin=.1;traceWidth=.15;availableZ=[];uniqueConnections=0;BOUNDARY_PADDING;lastCandidate=null;maxViaCount;minViaCount;phase="setup";progress=0;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??Ps(t.nodeWithPortPoints),this.hyperParameters=t.hyperParameters??{},this.SEGMENTS_PER_POLYLINE=t.hyperParameters?.SEGMENTS_PER_POLYLINE??3,this.BOUNDARY_PADDING=t.hyperParameters?.BOUNDARY_PADDING??.05,this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??this.viaDiameter,this.cellSize=this.nodeWithPortPoints.width/1024,this.candidates=[],this.availableZ=this.nodeWithPortPoints.availableZ??[0,1],this.bounds={minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2};const e=this.nodeWithPortPoints.width*this.nodeWithPortPoints.height,n=(this.viaDiameter+2*this.obstacleMargin+this.traceWidth/2)**2,s=new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size;this.uniqueConnections=s;const{numSameLayerCrossings:o,numEntryExitLayerChanges:i}=Ns(this.nodeWithPortPoints);if(this.minViaCount=2*o+i,this.maxViaCount=Math.min(Math.floor(e/n),Math.ceil(1.5*s)),this.minViaCount>this.SEGMENTS_PER_POLYLINE*(s/2))return this.failed=!0,void(this.error=`Not possible to solve problem with given SEGMENTS_PER_POLYLINE (${this.SEGMENTS_PER_POLYLINE}), atleast ${this.minViaCount} vias are required`);this.maxViaCount>this.SEGMENTS_PER_POLYLINE&&(this.maxViaCount=this.SEGMENTS_PER_POLYLINE),this.maxViaCount<this.minViaCount&&(this.maxViaCount=this.minViaCount)}computeMinGapBtwPolyLines(t){const e=[],n=[],s=[];for(let e=0;e<t.length;e++){const o=t[e],i=[o.start,...o.mPoints,o.end],r=new Map(this.availableZ.map(t=>[t,[]]));for(let t=0;t<i.length-1;t++){const e=[i[t],i[t+1]],n=e[0].z2;r.has(n)||r.set(n,[]),r.get(n).push(e)}n.push(r),s.push(i.filter(t=>t.z1!==t.z2))}for(let o=0;o<t.length;o++){const i=n[o],r=s[o];for(let a=o+1;a<t.length;a++){if(this.connMap?.areIdsConnected(t[o].connectionName,t[a].connectionName))continue;const c=n[a],h=s[a];let l=1;for(const t of this.availableZ){const e=i.get(t)??[],n=c.get(t)??[];for(const t of e)for(const e of n)l=Math.min(l,K(t[0],t[1],e[0],e[1])-this.traceWidth);for(const t of r)for(const e of n)l=Math.min(l,X(t,e[0],e[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of h)for(const n of e)l=Math.min(l,X(t,n[0],n[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of r)for(const e of h)l=Math.min(l,k(t,e)-this.viaDiameter)}e.push(l)}}return e}insertCandidate(t){let e=0,n=this.candidates.length-1;for(;e<=n;){const s=Math.floor((e+n)/2);this.candidates[s].f<t.f?e=s+1:n=s-1}this.candidates.splice(e,0,t)}setupInitialPolyLines(){const t=new Map;this.nodeWithPortPoints.portPoints.forEach(e=>{t.has(e.connectionName)?t.get(e.connectionName).end={...e,z1:e.z??0,z2:e.z??0}:t.set(e.connectionName,{start:{...e,z1:e.z??0,z2:e.z??0},end:null})});for(const[e,n]of t.entries())null===n.end&&t.delete(e);if(0===t.size)return this.failed=!0,void(this.error="No port pairs found, can't solve");const e=Array.from(t.entries()),n=((t,e,n,s)=>{const o=[];for(const[,n]of t){const t=n.start.z1!==n.end.z1,s=[];for(let n=0;n<=e;n++){const e=n%2!=0;t&&e?s.push(n):t||e||s.push(n)}o.push(s)}if(0===o.length)return[[]];let i=(t=>{if(!t||0===t.length)return[[]];let e=[[]];for(const n of t){const t=[];for(const s of e)for(const e of n)t.push([...s,e]);e=t}return e})(o).filter(t=>{for(let e=0;e<t.length;e++)if(t.reduce((t,e)=>t+e,0)<s)return!1;return!0});return i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(s.start.z1!==s.start.z2&&0===e[n])return!1}return!0}),i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(t[n][1].start.z1===t[n][1].start.z2)for(let o=n+1;o<t.length;o++){if(t[o][1].start.z1!==t[o][1].start.z2)continue;const[,i]=t[o];if(s.start.z1===s.end.z1&&i.start.z1===i.end.z1&&s.start.z1===i.start.z1&&L(s.start,s.end,i.start,i.end)&&e[n]+e[o]<2)return!1}}return!0}),i=i.filter(t=>!(t.reduce((t,e)=>t+e,0)>n)),i})(e,this.SEGMENTS_PER_POLYLINE,this.maxViaCount,this.minViaCount),s=(t=>{const{bounds:e,portPairsEntries:n,viaCountVariants:s}=t,{centroids:o}=Bs(e,n.map(([t,e])=>e)),i=[];for(const t of s){const n=t.reduce((t,e)=>t+e,0);let s=o;if(o.length<n){s=[];const t=Math.ceil(Math.sqrt(n)),o=t;for(let n=0;n<t;n++)for(let i=0;i<o;i++)s.push({x:e.minX+(i+1)/(o+1)*(e.maxX-e.minX),y:e.minY+(n+1)/(t+1)*(e.maxY-e.minY)})}const r=js(n,s.length);for(const e of r){const n=[];for(let t=0;t<e.length;t++)1===e[t]&&n.push(s[t]);i.push({viaPositions:n,viaCountVariant:t})}}return i})({portPairsEntries:e,viaCountVariants:n,bounds:this.bounds}),o=[];for(const{viaCountVariant:t,viaPositions:e}of s){const n=As(e);for(const e of n)o.push({viaCountVariant:t,viaPositions:e})}for(const{viaPositions:t,viaCountVariant:n}of o){const s=[];let o=0;for(let i=0;i<e.length;i++){const[r,a]=e[i],c=n[i],h=t.slice(o,o+c),l=Is({start:a.start,end:a.end,segmentsPerPolyline:this.SEGMENTS_PER_POLYLINE,viaPositions:h,viaCount:c,availableZ:this.availableZ});o+=c,s.push({connectionName:r,start:a.start,end:a.end,mPoints:l})}if(Os(s,this.bounds))continue;const i=this.computeMinGapBtwPolyLines(s),r=this.computeH({minGaps:i,forces:[]}),a={polyLines:s,g:0,h:r,f:r,viaCount:n.reduce((t,e)=>t+e,0),minGaps:i};if(this.checkIfSolved(a))return void(this.candidates=[a]);if(this.candidates.push(a),this.candidates.length>this.MAX_CANDIDATES)return}this.candidates.sort((t,e)=>t.f-e.f)}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){let e=0;for(const n of t.forces??[])for(const t of n)for(const n of t.values())e+=n.fx*n.fx+n.fy*n.fy;return e}getNeighbors(t){const{polyLines:e}=t,n=e.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(t,n)=>Array.from({length:e[n].mPoints.length},()=>new Map)),a=(t,n,s,o,i)=>{if(n>0&&n<e[t].mPoints.length+1){const e=n-1,a=r[t][e],c=a.get(s)||{fx:0,fy:0};a.set(s,{fx:c.fx+o,fy:c.fy+i})}};for(let t=0;t<n;t++)for(let o=t+1;o<n;o++){const n=e[t],r=e[o],c=[n.start,...n.mPoints,n.end],h=[r.start,...r.mPoints,r.end],l=[],d=[];for(let t=0;t<c.length-1;t++)l.push({p1:c[t],p2:c[t+1],layer:c[t].z2,p1Idx:t,p2Idx:t+1});c.forEach((t,e)=>{t.z1!==t.z2&&d.push({point:t,layers:[t.z1,t.z2],index:e})});const u=[],p=[];for(let t=0;t<h.length-1;t++)u.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&p.push({point:t,layers:[t.z1,t.z2],index:e})});for(const e of l)for(const n of u)if(e.layer===n.layer){if(K(e.p1,e.p2,n.p1,n.p2)<i)continue;const s={x:(e.p1.x+e.p2.x)/2,y:(e.p1.y+e.p2.y)/2},r={x:(n.p1.x+n.p2.x)/2,y:(n.p1.y+n.p2.y)/2},c=s.x-r.x,h=s.y-r.y,l=c*c+h*h;if(l>i){const s=Math.sqrt(l),r=(Math.exp(-6*s),`seg:${o}:${n.p1Idx}:${n.p2Idx}`),c=`seg:${t}:${e.p1Idx}:${e.p2Idx}`,h=(t,e,n,s,o,r,c)=>{const h=tt(t,n.p1,n.p2),l=t.x-h.x,d=t.y-h.y,u=l*l+d*d;if(u<=i)return;const p=Math.sqrt(u),f=.02*Math.exp(-6*p),m=l/p*f,g=d/p*f;a(s,e,r,m,g),a(o,n.p1Idx,c,-m/2,-g/2),a(o,n.p2Idx,c,-m/2,-g/2)};h(e.p1,e.p1Idx,n,t,o,r,c),h(e.p2,e.p2Idx,n,t,o,r,c),h(n.p1,n.p1Idx,e,o,t,c,r),h(n.p2,n.p2Idx,e,o,t,c,r)}}for(const e of d)for(const n of u)if(e.layers.includes(n.layer)){const r=tt(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${o}:${n.p1Idx}:${n.p2Idx}`;a(t,e.index,g,f,m);const y=`via:${t}:${e.index}`;a(o,n.p1Idx,y,-f/2,-m/2),a(o,n.p2Idx,y,-f/2,-m/2)}}for(const e of p)for(const n of l)if(e.layers.includes(n.layer)){const r=tt(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${t}:${n.p1Idx}:${n.p2Idx}`;a(o,e.index,g,f,m);const y=`via:${o}:${e.index}`;a(t,n.p1Idx,y,-f/2,-m/2),a(t,n.p2Idx,y,-f/2,-m/2)}}for(const e of d)for(const n of p){if(e.layers.filter(t=>n.layers.includes(t)).length>0){const r=e.point.x-n.point.x,c=e.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p,g=`via:${o}:${n.index}`,y=`via:${t}:${e.index}`;a(t,e.index,g,f,m),a(o,n.index,y,-f,-m)}}}}for(let t=0;t<n;t++){const n=e[t],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let e=0;e<r.length;e++)for(let n=e+1;n<r.length;n++){const o=r[e],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const e=Math.sqrt(d);let n=2,r=e;e<this.viaDiameter?(n*=4,r=Math.max(i,e)):r=Math.max(i,e-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/e*u,f=l/e*u,m=`via:${t}:${c.index}`,g=`via:${t}:${o.index}`;a(t,o.index,m,p,f),a(t,c.index,g,-p,-f)}}}const c=e.map(t=>({...t,mPoints:t.mPoints.map(t=>({...t}))}));let h=!1;for(let t=0;t<n;t++)for(let e=0;e<c[t].mPoints.length;e++){const n=c[t].mPoints[e],s=r[t][e],a={fx:0,fy:0};for(const t of s.values())a.fx+=t.fx,a.fy+=t.fy;const l=n.z1!==n.z2;let d=n.x+a.fx,u=n.y+a.fy;if(l){const t=this.viaDiameter/2;let e=0,s=0;const i=this.viaDiameter/2+this.BOUNDARY_PADDING,r=this.bounds.minX+i,c=this.bounds.maxX-i,h=this.bounds.minY+i,l=this.bounds.maxY-i,p=r+t-n.x,f=n.x-(c-t),m=h+t-n.y,g=n.y-(l-t);p>0?e=o*(Math.exp(p/(2*this.obstacleMargin))-1):f>0&&(e=-.008*(Math.exp(f/(2*this.obstacleMargin))-1)),m>0?s=o*(Math.exp(m/(2*this.obstacleMargin))-1):g>0&&(s=-.008*(Math.exp(g/(2*this.obstacleMargin))-1)),a.fx+=e,a.fy+=s,d=n.x+a.fx,u=n.y+a.fy}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;d=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,d)),u=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,u))}Math.abs(a.fx)<i&&Math.abs(a.fy)<i||(Math.abs(n.x-d)>i||Math.abs(n.y-u)>i)&&(n.x=d,n.y=u,h=!0)}if(!h)return[];const l=this.computeMinGapBtwPolyLines(c),d=this.computeG(c,t),u=this.computeH({minGaps:l,forces:r});return[{polyLines:c,g:d,h:u,f:Math.round(5*d)/5+u,minGaps:l,forces:r,viaCount:t.viaCount}]}checkIfSolved(t){const e=t.minGaps.every(t=>t>=this.obstacleMargin),n=t.polyLines.every(t=>t.mPoints.every(t=>{const e=(t.z1!==t.z2?this.viaDiameter/2:this.traceWidth/2)+this.BOUNDARY_PADDING;return((t,e,n=0)=>t.x>=e.minX+n&&t.x<=e.maxX-n&&t.y>=e.minY+n&&t.y<=e.maxY-n)(t,this.bounds,e)}));return e&&n}tryFinalAcceptance(){const t=this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP??void 0;if(void 0===t||null===this.lastCandidate||0===this.lastCandidate.minGaps.length)return;return Math.min(...this.lastCandidate.minGaps)>=t?(this.solved=!0,void this._setSolvedRoutes()):void 0}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return this.failed=!0,void(this.error="No candidates left")}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();if(!t)return void(this.failed=!0);const e=this.getNeighbors(t);for(const t of e)this.insertCandidate(t)}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"MultiHeadPolyLineIntraNodeSolver Visualization"};t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray"});const e=this.lastCandidate??this.candidates[0];if(e?.hasClosedSameLayerFace){const e=.1*(this.bounds.maxX-this.bounds.minX),n=.1*(this.bounds.maxY-this.bounds.minY);t.rects.push({center:{x:this.bounds.maxX+.6*e,y:this.bounds.maxY+.6*n},width:e,height:n,fill:"red",label:"HAS CLOSED FACE"})}for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:`${e.connectionName} (Port z=${e.z??0})`,color:this.colorMap[e.connectionName]??"blue"});return e&&e.polyLines.forEach((n,s)=>{const o=this.colorMap[n.connectionName]??"purple",i=[n.start,...n.mPoints,n.end];for(let e=0;e<i.length-1;e++){const s=i[e],r=i[e+1],a=s.z2,c=0===a,h=c?o:In(o,.5);t.lines.push({points:[s,r],strokeColor:h,strokeWidth:this.traceWidth,strokeDash:c?void 0:[.15,.15],label:`${n.connectionName} segment (z=${a})`})}i.forEach((r,a)=>{const c=r.z1!==r.z2,h=r.z1,l=a>0&&a<i.length-1;let d="",u="";if(l){const o=a-1,i=e.forces?.[s]?.[o];if(i&&i.size>0){const s={fx:0,fy:0};i.forEach((i,a)=>{if(s.fx+=i.fx,s.fy+=i.fy,Math.abs(i.fx)>1e-6||Math.abs(i.fy)>1e-6){const s=a.split(":"),c=s[0],h=parseInt(s[1],10),l=e.polyLines[h],d=this.colorMap[l.connectionName]??"gray",u=20,p={x:r.x+i.fx*u,y:r.y+i.fy*u};let f=l.connectionName;if("via"===c){f+=` Via ${parseInt(s[2],10)}`}else if("seg"===c){f+=` Seg ${parseInt(s[2],10)}-${parseInt(s[3],10)}`}t.lines.push({points:[r,p],strokeColor:d,strokeWidth:.02,strokeDash:"2,2",label:`Force by ${f} on ${n.connectionName} mPoint ${o}`})}}),(Math.abs(s.fx)>1e-6||Math.abs(s.fy)>1e-6)&&(u=`\nNet Force: (${s.fx.toFixed(3)}, ${s.fy.toFixed(3)})`)}}if(c)d=`Via (${n.connectionName} z=${r.z1} -> z=${r.z2})${u}`,t.circles.push({center:r,radius:this.viaDiameter/2,fill:In(o,.5),label:d});else if(l){const e=0===h?o:In(o,.5);d=`mPoint (${n.connectionName} z=${h})${u}`,t.circles.push({center:r,radius:this.cellSize/8,fill:e,label:d})}})}),t}_setSolvedRoutes(){if(!this.solved||!this.lastCandidate)return[];const t=[];for(const e of this.lastCandidate.polyLines){const n=[],s=[],o=[e.start,...e.mPoints,e.end];for(let t=0;t<o.length;t++){const e=o[t];n.push({x:e.x,y:e.y,z:e.z1}),e.z1!==e.z2&&(s.push({x:e.x,y:e.y}),n.push({x:e.x,y:e.y,z:e.z2}))}t.push({connectionName:e.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:n,vias:s})}this.solvedRoutes=t}},Hs=class extends Ws{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver2"}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){const{minGaps:e}=t;let n=0;for(const t of e)t<0&&(n+=this.obstacleMargin),t<this.obstacleMargin&&(n+=this.obstacleMargin-t);return.011*n}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return void(this.failed=!0)}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();let e=!1,n=0;const s=void 0===t.magForceApplied?1:10;for(let o=0;o<s;o++){const s=this.applyForcesToPolyLines(t.polyLines);if(n+=s.magForceApplied,e=s.lastStepMoved,!s.lastStepMoved)break}if(t.magForceApplied=n,t.minGaps=this.computeMinGapBtwPolyLines(t.polyLines),this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();t.g=this.computeG(t.polyLines,t),t.h=this.computeH(t),t.f=t.g+t.h,e&&this.insertCandidate(t)}applyForcesToPolyLines(t){let e=0;const n=t.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(e,n)=>Array.from({length:t[n].mPoints.length},()=>({fx:0,fy:0}))),a=(e,n,s,o)=>{if(n>0&&n<t[e].mPoints.length+1){const t=n-1;r[e][t].fx+=s,r[e][t].fy+=o}},c=(t,e,n,s,o)=>{const r=tt(t,n.p1,n.p2),c=t.x-r.x,h=t.y-r.y,l=c*c+h*h;if(l<=i)return;const d=Math.sqrt(l),u=.02*Math.exp(-6*d),p=c/d*u,f=h/d*u;a(s,e,p,f),a(o,n.p1Idx,-p/2,-f/2),a(o,n.p2Idx,-p/2,-f/2)};for(let e=0;e<n;e++)for(let o=e+1;o<n;o++){const n=t[e],r=t[o],h=[n.start,...n.mPoints,n.end],l=[r.start,...r.mPoints,r.end],d=[],u=[];for(let t=0;t<h.length-1;t++)d.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&u.push({point:t,layers:[t.z1,t.z2],index:e})});const p=[],f=[];for(let t=0;t<l.length-1;t++)p.push({p1:l[t],p2:l[t+1],layer:l[t].z2,p1Idx:t,p2Idx:t+1});l.forEach((t,e)=>{t.z1!==t.z2&&f.push({point:t,layers:[t.z1,t.z2],index:e})});for(const t of d)for(const n of p)if(t.layer===n.layer){K(t.p1,t.p2,n.p1,n.p2);c(t.p1,t.p1Idx,n,e,o),c(t.p2,t.p2Idx,n,e,o),c(n.p1,n.p1Idx,t,o,e),c(n.p2,n.p2Idx,t,o,e)}for(const t of u)for(const n of p)if(t.layers.includes(n.layer)){const r=tt(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(e,t.index,f,m),a(o,n.p1Idx,-f/2,-m/2),a(o,n.p2Idx,-f/2,-m/2)}}for(const t of f)for(const n of d)if(t.layers.includes(n.layer)){const r=tt(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(o,t.index,f,m),a(e,n.p1Idx,-f/2,-m/2),a(e,n.p2Idx,-f/2,-m/2)}}for(const t of u)for(const n of f){if(t.layers.filter(t=>n.layers.includes(t)).length>0){const r=t.point.x-n.point.x,c=t.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p;a(e,t.index,f,m),a(o,n.index,-f,-m)}}}}for(let e=0;e<n;e++){const n=t[e],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let t=0;t<r.length;t++)for(let n=t+1;n<r.length;n++){const o=r[t],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const t=Math.sqrt(d);let n=2,r=t;t<this.viaDiameter?(n*=4,r=Math.max(i,t)):r=Math.max(i,t-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/t*u,f=l/t*u;a(e,o.index,p,f),a(e,c.index,-p,-f)}}}let h=!1;for(let s=0;s<n;s++)for(let n=0;n<t[s].mPoints.length;n++){const a=t[s].mPoints[n],c=r[s][n],l=a.z1!==a.z2;let d=c.fx,u=c.fy,p=a.x+d,f=a.y+u;if(l){const t=this.viaDiameter/2;let e=0,n=0;const s=this.viaDiameter/2+this.BOUNDARY_PADDING,i=this.bounds.minX+s,r=this.bounds.maxX-s,c=this.bounds.minY+s,h=this.bounds.maxY-s,l=i+t-a.x,m=a.x-(r-t),g=c+t-a.y,y=a.y-(h-t);l>0?e=o*(Math.exp(l/(2*this.obstacleMargin))-1):m>0&&(e=-.008*(Math.exp(m/(2*this.obstacleMargin))-1)),g>0?n=o*(Math.exp(g/(2*this.obstacleMargin))-1):y>0&&(n=-.008*(Math.exp(y/(2*this.obstacleMargin))-1)),d+=e,u+=n,p=a.x+d,f=a.y+u}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;p=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,p)),f=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,f))}if(Math.abs(d)<i&&Math.abs(u)<i)continue;e+=Math.sqrt(d*d+u*u),(Math.abs(a.x-p)>i||Math.abs(a.y-f)>i)&&(a.x=p,a.y=f,h=!0)}return{lastStepMoved:h,magForceApplied:e}}},Us=t=>t.flatMap(t=>`${t.connectionName}-${t.mPoints.map(t=>`${t.x.toFixed(2)},${t.y.toFixed(2)},${t.z1},${t.z2}`)}`).sort().join("|");var Vs=class extends Hs{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver3"}constructor(t){super(t),this.MAX_ITERATIONS=1e3}createInitialCandidateFromSeed(t){const e=new Ss({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:{SHUFFLE_SEED:t},viaDiameter:this.viaDiameter});if(e.solve(),e.failed||!e.solved)return this.failed=!0,this.error=`ViaPossibilitiesSolver2 failed with: ${e.error}`,null;const n=[];let s=0;for(const[t,o]of e.completedPaths.entries()){if(o.length<2){console.warn(`Skipping connection "${t}" due to insufficient points (${o.length}) in ViaPossibilitiesSolver2 path.`);continue}const e=o[0],i=o[o.length-1],r=o.slice(1,-1),a=[];let c=0,h=e.z;for(let t=0;t<r.length;t++){const e=r[t],n=t+1<r.length?r[t+1]:i,s=h,o=t+1<r.length&&e.x===n.x&&e.y===n.y&&e.z!==n.z?n.z:e.z;a.push({x:e.x,y:e.y,z1:s,z2:o}),s!==o?(c++,t++,h=o):h=e.z}s+=c;const l=this.SEGMENTS_PER_POLYLINE;let d=a.length+1;for(;d<l;){let n=-1,s=-1,o=null,r=null;const c=[{...e,z1:e.z,z2:e.z,connectionName:t},...a,{...i,z1:i.z,z2:i.z,connectionName:t}];for(let t=0;t<c.length-1;t++){const e=c[t],i=c[t+1];if(e.x===i.x&&e.y===i.y)continue;const a=k(e,i);a>n&&(n=a,s=t,o=e,r=i)}if(-1===s||!o||!r){console.warn(`Could not find longest segment for ${t} while trying to reach ${l} segments.`);break}const h=(o.x+r.x)/2,u=(o.y+r.y)/2,p=o.z2,f={x:h,y:u,z1:p,z2:p};a.splice(s,0,f),d++}n.push({connectionName:t,start:{...e,z1:e.z,z2:e.z},end:{...i,z1:i.z,z2:i.z},mPoints:a})}if(0===n.length)return this.failed=!0,this.error="No valid polylines generated from ViaPossibilitiesSolver2.",console.error(this.error),null;const o=this.computeMinGapBtwPolyLines(n),i=this.computeH({minGaps:o,forces:[]}),r={polyLines:n,g:0,h:i,f:0+i,viaCount:s,minGaps:o};return r.g=this.computeG(n,r),r.f=r.g+r.h,r}setupInitialPolyLines(){this.candidates=[];const t=Math.min(2e3,function(t){if(!Number.isInteger(t)||t<0)throw new RangeError("n must be a non-negative integer");let e=1;for(let n=2;n<=t;n++)e*=n;return e}(this.uniqueConnections)),e=new Set;for(let n=0;n<t;n++){const t=this.createInitialCandidateFromSeed(n);if(!t)continue;const s=Us(t.polyLines);e.has(s)||(e.add(s),this.candidates.push(t))}this.candidates.sort((t,e)=>t.f-e.f)}};import{HighDensitySolverA01 as Gs}from"@tscircuit/high-density-a01";var Zs=Object.create,qs=Object.defineProperty,Js=Object.getOwnPropertyDescriptor,Ks=Object.getOwnPropertyNames,Qs=Object.getPrototypeOf,to=Object.prototype.hasOwnProperty,eo=(t,e)=>function(){return e||(0,t[Ks(t)[0]])((e={exports:{}}).exports,e),e.exports},no=eo({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>=0?(i=r,o=r-1):s=r+1}return i}function s(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>0?(i=r,o=r-1):s=r+1}return i}function o(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<0?(i=r,s=r+1):o=r-1}return i}function i(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<=0?(i=r,s=r+1):o=r-1}return i}function r(t,e,n,s,o){for(;s<=o;){var i=s+o>>>1,r=t[i],a=void 0!==n?n(r,e):r-e;if(0===a)return i;a<=0?s=i+1:o=i-1}return-1}function a(t,e,n,s,o,i){return"function"==typeof n?i(t,e,n,void 0===s?0:0|s,void 0===o?t.length-1:0|o):i(t,e,void 0,void 0===n?0:0|n,void 0===s?t.length-1:0|s)}e.exports={ge:function(t,e,s,o,i){return a(t,e,s,o,i,n)},gt:function(t,e,n,o,i){return a(t,e,n,o,i,s)},lt:function(t,e,n,s,i){return a(t,e,n,s,i,o)},le:function(t,e,n,s,o){return a(t,e,n,s,o,i)},eq:function(t,e,n,s,o){return a(t,e,n,s,o,r)}}}}),so=eo({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,s){var o=t*e,i=n*t,r=i-(i-t),a=t-r,c=n*e,h=c-(c-e),l=e-h,d=a*l-(o-r*h-a*h-r*l);if(s)return s[0]=d,s[1]=o,s;return[d,o]};var n=+(Math.pow(2,27)+1)}}),oo=eo({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),io=eo({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var s=t+e,o=s-t,i=e-o,r=t-(s-o);if(n)return n[0]=r+i,n[1]=s,n;return[r+i,s]}}}),ro=eo({"node_modules/robust-scale/robust-scale.js"(t,e){var n=so(),s=io();e.exports=function(t,e){var o=t.length;if(1===o){var i=n(t[0],e);return i[0]?i:[i[1]]}var r=new Array(2*o),a=[.1,.1],c=[.1,.1],h=0;n(t[0],e,a),a[0]&&(r[h++]=a[0]);for(var l=1;l<o;++l){n(t[l],e,c);var d=a[1];s(d,c[0],a),a[0]&&(r[h++]=a[0]);var u=c[1],p=a[1],f=u+p,m=p-(f-u);a[1]=f,m&&(r[h++]=m)}a[1]&&(r[h++]=a[1]);0===h&&(r[h++]=0);return r.length=h,r}}}),ao=eo({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],-e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=-e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=-e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=-e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),co=eo({"node_modules/robust-orientation/orientation.js"(t,e){var n=so(),s=oo(),o=ro(),i=ao();function r(t,e,n,s){return function(n,o,i){var r=t(t(e(o[1],i[0]),e(-i[1],o[0])),t(e(n[1],o[0]),e(-o[1],n[0]))),a=t(e(n[1],i[0]),e(-i[1],n[0])),c=s(r,a);return c[c.length-1]}}function a(t,e,n,s){return function(o,i,r,a){var c=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2])))),h=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2])))),l=s(c,h);return l[l.length-1]}}function c(t,e,n,s){return function(o,i,r,a,c){var h=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),i[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),-r[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),a[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),-c[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-i[3])))),t(t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),a[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),-c[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),o[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-i[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-a[3]))))),l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-r[3])),t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),a[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),o[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),-i[3])),t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-c[3])))),d=s(h,l);return d[d.length-1]}}function h(t){return(3===t?r:4===t?a:c)(s,n,o,i)}var l=h(3),d=h(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var s,o=(t[1]-n[1])*(e[0]-n[0]),i=(t[0]-n[0])*(e[1]-n[1]),r=o-i;if(o>0){if(i<=0)return r;s=o+i}else{if(!(o<0))return r;if(i>=0)return r;s=-(o+i)}var a=33306690738754716e-32*s;return r>=a||r<=-a?r:l(t,e,n)},function(t,e,n,s){var o=t[0]-s[0],i=e[0]-s[0],r=n[0]-s[0],a=t[1]-s[1],c=e[1]-s[1],h=n[1]-s[1],l=t[2]-s[2],u=e[2]-s[2],p=n[2]-s[2],f=i*h,m=r*c,g=r*a,y=o*h,x=o*c,v=i*a,b=l*(f-m)+u*(g-y)+p*(x-v),P=7771561172376103e-31*((Math.abs(f)+Math.abs(m))*Math.abs(l)+(Math.abs(g)+Math.abs(y))*Math.abs(u)+(Math.abs(x)+Math.abs(v))*Math.abs(p));return b>P||-b>P?b:d(t,e,n,s)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=h(t.length)),e.apply(void 0,t)}function f(t,e,n,s,o,i,r){return function(e,n,a,c,h){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,a);case 4:return i(e,n,a,c);case 5:return r(e,n,a,c,h)}for(var l=new Array(arguments.length),d=0;d<arguments.length;++d)l[d]=arguments[d];return t(l)}}!function(){for(;u.length<=5;)u.push(h(u.length));e.exports=f.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),ho=eo({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=no(),s=co()[3];function o(t,e,n,s,o){this.a=t,this.b=e,this.idx=n,this.lowerIds=s,this.upperIds=o}function i(t,e,n,s){this.a=t,this.b=e,this.type=n,this.idx=s}function r(t,e){var n=t.a[0]-e.a[0]||t.a[1]-e.a[1]||t.type-e.type;return n||(0!==t.type&&(n=s(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return s(t.a,t.b,e)}function c(t,e,o,i,r){for(var c=n.lt(e,i,a),h=n.gt(e,i,a),l=c;l<h;++l){for(var d=e[l],u=d.lowerIds,p=u.length;p>1&&s(o[u[p-2]],o[u[p-1]],i)>0;)t.push([u[p-1],u[p-2],r]),p-=1;u.length=p,u.push(r);var f=d.upperIds;for(p=f.length;p>1&&s(o[f[p-2]],o[f[p-1]],i)<0;)t.push([f[p-2],f[p-1],r]),p-=1;f.length=p,f.push(r)}}function h(t,e){var n;return(n=t.a[0]<e.a[0]?s(t.a,t.b,e.a):s(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?s(t.a,t.b,e.b):s(e.b,e.a,t.b))||t.idx-e.idx}function l(t,e,s){var i=n.le(t,s,h),r=t[i],a=r.upperIds,c=a[a.length-1];r.upperIds=[c],t.splice(i+1,0,new o(s.a,s.b,s.idx,[c],a))}function d(t,e,s){var o=s.a;s.a=s.b,s.b=o;var i=n.eq(t,s,h),r=t[i];t[i-1].upperIds=r.upperIds,t.splice(i,1)}e.exports=function(t,e){for(var n=t.length,s=e.length,a=[],h=0;h<n;++h)a.push(new i(t[h],null,0,h));for(h=0;h<s;++h){var u=e[h],p=t[u[0]],f=t[u[1]];p[0]<f[0]?a.push(new i(p,f,2,h),new i(f,p,1,h)):p[0]>f[0]&&a.push(new i(f,p,2,h),new i(p,f,1,h))}a.sort(r);for(var m=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),g=[new o([m,1],[m,0],-1,[],[],[],[])],y=[],x=(h=0,a.length);h<x;++h){var v=a[h],b=v.type;0===b?c(y,g,t,v.a,v.idx):2===b?l(g,t,v):d(g,t,v)}return y}}}),lo=eo({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=no();function s(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),o=0;o<t;++o)n[o]=[];return new s(n,e)};var o=s.prototype;function i(t,e,n){for(var s=1,o=t.length;s<o;s+=2)if(t[s-1]===e&&t[s]===n)return t[s-1]=t[o-2],t[s]=t[o-1],void(t.length=o-2)}o.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(s,o){return t[0]=Math.min(s,o),t[1]=Math.max(s,o),n.eq(this.edges,t,e)>=0}}(),o.removeTriangle=function(t,e,n){var s=this.stars;i(s[t],e,n),i(s[e],n,t),i(s[n],t,e)},o.addTriangle=function(t,e,n){var s=this.stars;s[t].push(e,n),s[e].push(n,t),s[n].push(t,e)},o.opposite=function(t,e){for(var n=this.stars[e],s=1,o=n.length;s<o;s+=2)if(n[s]===t)return n[s-1];return-1},o.flip=function(t,e){var n=this.opposite(t,e),s=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,s),this.addTriangle(t,s,n),this.addTriangle(e,n,s)},o.edges=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2)e.push([o[i],o[i+1]]);return e},o.cells=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2){var a=o[i],c=o[i+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),uo=eo({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=so(),s=oo(),o=ao(),i=ro();function r(t){return(3===t?a:4===t?c:5===t?h:l)(s,o,n,i)}function a(t,e,n,s){return function(o,i,r){var a=n(o[0],o[0]),c=s(a,i[0]),h=s(a,r[0]),l=n(i[0],i[0]),d=s(l,o[0]),u=s(l,r[0]),p=n(r[0],r[0]),f=s(p,o[0]),m=s(p,i[0]),g=t(e(m,u),e(d,c)),y=e(f,h),x=e(g,y);return x[x.length-1]}}function c(t,e,n,s){return function(o,i,r,a){var c=t(n(o[0],o[0]),n(o[1],o[1])),h=s(c,i[0]),l=s(c,r[0]),d=s(c,a[0]),u=t(n(i[0],i[0]),n(i[1],i[1])),p=s(u,o[0]),f=s(u,r[0]),m=s(u,a[0]),g=t(n(r[0],r[0]),n(r[1],r[1])),y=s(g,o[0]),x=s(g,i[0]),v=s(g,a[0]),b=t(n(a[0],a[0]),n(a[1],a[1])),P=s(b,o[0]),S=s(b,i[0]),M=s(b,r[0]),N=t(t(s(e(M,v),i[1]),t(s(e(S,m),-r[1]),s(e(x,f),a[1]))),t(s(e(S,m),o[1]),t(s(e(P,d),-i[1]),s(e(p,h),a[1])))),I=t(t(s(e(M,v),o[1]),t(s(e(P,d),-r[1]),s(e(y,l),a[1]))),t(s(e(x,f),o[1]),t(s(e(y,l),-i[1]),s(e(p,h),r[1])))),_=e(N,I);return _[_.length-1]}}function h(t,e,n,s){return function(o,i,r,a,c){var h=t(n(o[0],o[0]),t(n(o[1],o[1]),n(o[2],o[2]))),l=s(h,i[0]),d=s(h,r[0]),u=s(h,a[0]),p=s(h,c[0]),f=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),m=s(f,o[0]),g=s(f,r[0]),y=s(f,a[0]),x=s(f,c[0]),v=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),b=s(v,o[0]),P=s(v,i[0]),S=s(v,a[0]),M=s(v,c[0]),N=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),I=s(N,o[0]),_=s(N,i[0]),C=s(N,r[0]),T=s(N,c[0]),E=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),w=s(E,o[0]),R=s(E,i[0]),O=s(E,r[0]),A=s(E,a[0]),z=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),i[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),-r[2]),s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),a[2]))),t(s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),-c[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-i[2])))),t(t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),a[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),-c[2]),s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),o[2]))),t(s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-i[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-a[2]))))),D=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-r[2])),t(s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),a[2]),s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-c[2]))),t(t(s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),o[2]),s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),-i[2])),t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-c[2])))),L=e(z,D);return L[L.length-1]}}function l(t,e,n,s){return function(o,i,r,a,c,h){var l=t(t(n(o[0],o[0]),n(o[1],o[1])),t(n(o[2],o[2]),n(o[3],o[3]))),d=s(l,i[0]),u=s(l,r[0]),p=s(l,a[0]),f=s(l,c[0]),m=s(l,h[0]),g=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),y=s(g,o[0]),x=s(g,r[0]),v=s(g,a[0]),b=s(g,c[0]),P=s(g,h[0]),S=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),M=s(S,o[0]),N=s(S,i[0]),I=s(S,a[0]),_=s(S,c[0]),C=s(S,h[0]),T=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),E=s(T,o[0]),w=s(T,i[0]),R=s(T,r[0]),O=s(T,c[0]),A=s(T,h[0]),z=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),D=s(z,o[0]),L=s(z,i[0]),F=s(z,r[0]),Y=s(z,a[0]),X=s(z,h[0]),k=t(t(n(h[0],h[0]),n(h[1],h[1])),t(n(h[2],h[2]),n(h[3],h[3]))),$=s(k,o[0]),B=s(k,i[0]),j=s(k,r[0]),W=s(k,a[0]),H=s(k,c[0]),U=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),i[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),a[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),o[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-i[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),r[3])),t(s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),h[3]))))),V=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),o[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),r[3]),s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),o[3]))),t(t(s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),-i[3]),s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),r[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),c[3]))))),G=e(U,V);return G[G.length-1]}}var d=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=d[t.length];return e||(e=d[t.length]=r(t.length)),e.apply(void 0,t)}function p(t,e,n,s,o,i,r,a){return function(e,n,c,h,l,d){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,c);case 4:return i(e,n,c,h);case 5:return r(e,n,c,h,l);case 6:return a(e,n,c,h,l,d)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;d.length<=6;)d.push(r(d.length));e.exports=p.apply(void 0,[u].concat(d));for(var t=0;t<=6;++t)e.exports[t]=d[t]}()}}),po=eo({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=uo()[4];no();function s(t,e,s,o,i,r){var a=e.opposite(o,i);if(!(a<0)){if(i<o){var c=o;o=i,i=c,c=r,r=a,a=c}e.isConstraint(o,i)||n(t[o],t[i],t[r],t[a])<0&&s.push(o,i)}}e.exports=function(t,e){for(var o=[],i=t.length,r=e.stars,a=0;a<i;++a)for(var c=r[a],h=1;h<c.length;h+=2){if(!((p=c[h])<a)&&!e.isConstraint(a,p)){for(var l=c[h-1],d=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){d=c[u];break}d<0||n(t[a],t[p],t[l],t[d])<0&&o.push(a,p)}}for(;o.length>0;){for(var p=o.pop(),f=(l=-1,d=-1,c=r[a=o.pop()],1);f<c.length;f+=2){var m=c[f-1],g=c[f];m===p?d=g:g===p&&(l=m)}l<0||d<0||(n(t[a],t[p],t[l],t[d])>=0||(e.flip(a,p),s(t,e,o,l,a,d),s(t,e,o,a,d,l),s(t,e,o,d,p,l),s(t,e,o,p,l,d)))}}}}),fo=eo({"node_modules/cdt2d/lib/filter.js"(t,e){var n=no();function s(t,e,n,s,o,i,r){this.cells=t,this.neighbor=e,this.flags=s,this.constraint=n,this.active=o,this.next=i,this.boundary=r}function o(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var i=function(t,e){for(var n=t.cells(),i=n.length,r=0;r<i;++r){var a=(y=n[r])[0],c=y[1],h=y[2];c<h?c<a&&(y[0]=c,y[1]=h,y[2]=a):h<a&&(y[0]=h,y[1]=a,y[2]=c)}n.sort(o);var l=new Array(i);for(r=0;r<l.length;++r)l[r]=0;var d=[],u=[],p=new Array(3*i),f=new Array(3*i),m=null;e&&(m=[]);var g=new s(n,p,f,l,d,u,m);for(r=0;r<i;++r)for(var y=n[r],x=0;x<3;++x){a=y[x],c=y[(x+1)%3];var v=p[3*r+x]=g.locate(c,a,t.opposite(c,a)),b=f[3*r+x]=t.isConstraint(a,c);v<0&&(b?u.push(r):(d.push(r),l[r]=1),e&&m.push([c,a,-1]))}return g}(t,n);if(0===e)return n?i.cells.concat(i.boundary):i.cells;var r=1,a=i.active,c=i.next,h=i.flags,l=i.cells,d=i.constraint,u=i.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(h[p]!==-r){h[p]=r;l[p];for(var f=0;f<3;++f){var m=u[3*p+f];m>=0&&0===h[m]&&(d[3*p+f]?c.push(m):(a.push(m),h[m]=r))}}}var g=c;c=a,a=g,c.length=0,r=-r}var y=function(t,e,n){for(var s=0,o=0;o<t.length;++o)e[o]===n&&(t[s++]=t[o]);return t.length=s,t}(l,h,e);if(n)return y.concat(i.boundary);return y},s.prototype.locate=function(){var t=[0,0,0];return function(e,s,i){var r=e,a=s,c=i;return s<i?s<e&&(r=s,a=i,c=e):i<e&&(r=i,a=e,c=s),r<0?-1:(t[0]=r,t[1]=a,t[2]=c,n.eq(this.cells,t,o))}}()}}),mo=eo({"node_modules/cdt2d/cdt2d.js"(t,e){var n=ho(),s=lo(),o=po(),i=fo();function r(t){return[Math.min(t[0],t[1]),Math.max(t[0],t[1])]}function a(t,e){return t[0]-e[0]||t[1]-e[1]}function c(t,e,n){return e in t?t[e]:n}e.exports=function(t,e,h){Array.isArray(e)?(h=h||{},e=e||[]):(h=e||{},e=[]);var l=!!c(h,"delaunay",!0),d=!!c(h,"interior",!0),u=!!c(h,"exterior",!0),p=!!c(h,"infinity",!1);if(!d&&!u||0===t.length)return[];var f=n(t,e);if(l||d!==u||p){for(var m=s(t.length,function(t){return t.map(r).sort(a)}(e)),g=0;g<f.length;++g){var y=f[g];m.addTriangle(y[0],y[1],y[2])}return l&&o(t,m),u?d?p?i(m,0,p):m.cells():i(m,1,p):i(m,-1)}return f}}}),go=class{heap=[];maxSize;constructor(t=[],e=1e4){if(this.maxSize=e,t.length>0){this.heap=[...t].sort((t,e)=>t.f-e.f).slice(0,this.maxSize);for(let t=Math.floor(this.heap.length/2)-1;t>=0;t--)this._siftDown(t)}}get size(){return this.heap.length}isEmpty(){return 0===this.heap.length}peek(){return this.isEmpty()?null:this.heap[0]??null}peekMany(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}dequeue(){if(this.isEmpty())return null;const t=this.heap[0],e=this.heap.pop();return 0===this.heap.length&&void 0!==e||void 0!==e&&(this.heap[0]=e,this._siftDown(0)),t}enqueue(t){this.heap.length>=this.maxSize||(this.heap.push(t),this._siftUp(this.heap.length-1))}_siftUp(t){let e=t;for(;e>0;){const t=this._parentIndex(e);if(this.heap[t].f<=this.heap[e].f)break;this._swap(e,t),e=t}}_siftDown(t){let e=t;const n=this.heap.length;for(;;){const t=this._leftChildIndex(e),s=this._rightChildIndex(e);let o=e;if(t<n&&this.heap[t].f<this.heap[o].f&&(o=t),s<n&&this.heap[s].f<this.heap[o].f&&(o=s),o===e)break;this._swap(e,o),e=o}}_swap(t,e){[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]]}_parentIndex(t){return Math.floor((t-1)/2)}_leftChildIndex(t){return 2*t+1}_rightChildIndex(t){return 2*t+2}},yo=class extends N{constructor(t){super(),this.input=t,this.graph=(t=>{if(t.ports.length>0&&"region1"in t.ports[0]&&"object"==typeof t.ports[0].region1)return t;const e=new Map,n=new Map;for(const e of t.regions){const{assignments:t,...s}=e;n.set(e.regionId,{...s,ports:[],assignments:void 0})}for(const s of t.ports){const t=n.get(s.region1Id??s.region1?.regionId),o=n.get(s.region2Id??s.region2?.regionId),i={portId:s.portId,region1:t,region2:o,d:s.d};e.set(s.portId,i),t.ports.push(i),o.ports.push(i)}return{ports:Array.from(e.values()),regions:Array.from(n.values())}})(t.inputGraph);for(const t of this.graph.regions)t.assignments=[];this.connections=((t,e)=>{const n=[];for(const s of t)"startRegionId"in s?n.push({connectionId:s.connectionId,mutuallyConnectedNetworkId:s.connectionId,startRegion:e.regions.find(t=>t.regionId===s.startRegionId),endRegion:e.regions.find(t=>t.regionId===s.endRegionId)}):n.push(s);return n})(t.inputConnections,this.graph),void 0!==t.greedyMultiplier&&(this.greedyMultiplier=t.greedyMultiplier),void 0!==t.rippingEnabled&&(this.rippingEnabled=t.rippingEnabled),void 0!==t.ripCost&&(this.ripCost=t.ripCost),this.unprocessedConnections=[...this.connections],this.candidateQueue=new go,this.beginNewConnection()}getSolverName(){return"HyperGraphSolver"}graph;connections;candidateQueue;unprocessedConnections;solvedRoutes=[];currentConnection=null;currentEndRegion=null;greedyMultiplier=1;rippingEnabled=!1;ripCost=0;lastCandidate=null;visitedPointsForCurrentConnection=new Map;getConstructorParams(){return{inputGraph:(e=this.graph,{ports:e.ports.map(t=>({portId:t.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:t.d})),regions:e.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.portId),d:t.d}))}),inputConnections:(t=this.connections,t.map(t=>({connectionId:t.connectionId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId}))),greedyMultiplier:this.greedyMultiplier,rippingEnabled:this.rippingEnabled,ripCost:this.ripCost};var t,e}computeH(t){return this.estimateCostToEnd(t.port)}estimateCostToEnd(t){return 0}getPortUsagePenalty(t){return 0}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){return 0}getRipsRequiredForPortUsage(t,e,n){return[]}isRipRequiredForPortUsage(t,e,n){return!1}isTransitionAllowed(t,e,n){return!0}computeG(t){return t.parent.g+this.computeIncreasedRegionCostIfPortsAreUsed(t.lastRegion,t.lastPort,t.port)+(t.ripRequired?this.ripCost:0)+this.getPortUsagePenalty(t.port)}selectCandidatesForEnteringRegion(t){return t}computeRoutesToRip(t){const e=this.computeCrossingRoutes(t),n=this.computePortOverlapRoutes(t);return new Set([...e,...n])}computePortOverlapRoutes(t){const e=new Set;for(const n of t.path)n.port.assignment&&n.port.assignment.connection.mutuallyConnectedNetworkId!==t.connection.mutuallyConnectedNetworkId&&e.add(n.port.assignment.solvedRoute);return e}computeCrossingRoutes(t){const e=new Set;for(const n of t.path){if(!n.lastPort||!n.lastRegion)continue;const t=this.getRipsRequiredForPortUsage(n.lastRegion,n.lastPort,n.port);for(const n of t)e.add(n.solvedRoute)}return e}getNextCandidates(t){const e=t.nextRegion,n=t.port,s={};for(const o of e.ports){if(o===t.port)continue;if(!this.isTransitionAllowed(e,n,o))continue;const i=o.assignment&&o.assignment.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId||this.isRipRequiredForPortUsage(e,n,o),r={port:o,hops:t.hops+1,parent:t,lastRegion:e,nextRegion:o.region1===e?o.region2:o.region1,lastPort:n,ripRequired:i};!this.rippingEnabled&&r.ripRequired||(s[r.nextRegion.regionId]??=[],s[r.nextRegion.regionId].push(r))}const o=[];for(const t in s){const e=s[t];o.push(...this.selectCandidatesForEnteringRegion(e))}for(const t of o)t.g=this.computeG(t),t.h=this.computeH(t),t.f=t.g+t.h*this.greedyMultiplier;return o}processSolvedRoute(t){const e={path:[],connection:this.currentConnection,requiredRip:!1};let n=t,s=!1;for(;n;)s||=!!n.ripRequired,e.path.unshift(n),n=n.parent;s&&(e.requiredRip=!0);const o=this.computeRoutesToRip(e);if(o.size>0){e.requiredRip=!0;for(const t of o)this.ripSolvedRoute(t)}for(const t of e.path){if(t.port.assignment={solvedRoute:e,connection:this.currentConnection},!t.lastPort)continue;const n={regionPort1:t.lastPort,regionPort2:t.port,region:t.lastRegion,connection:this.currentConnection,solvedRoute:e};t.lastRegion.assignments?.push(n)}this.solvedRoutes.push(e),this.routeSolvedHook(e)}routeSolvedHook(t){}routeStartedHook(t){}ripSolvedRoute(t){for(const e of t.path.map(t=>t.port))e.ripCount=(e.ripCount??0)+1,e.region1.assignments=e.region1.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.region2.assignments=e.region2.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.assignment=void 0;this.solvedRoutes=this.solvedRoutes.filter(e=>e!==t),this.unprocessedConnections.push(t.connection)}beginNewConnection(){this.currentConnection=this.unprocessedConnections.shift(),this.currentEndRegion=this.currentConnection.endRegion,this.candidateQueue=new go,this.visitedPointsForCurrentConnection.clear(),this.routeStartedHook(this.currentConnection);for(const t of this.currentConnection.startRegion.ports)this.candidateQueue.enqueue({port:t,g:0,h:0,f:0,hops:0,ripRequired:!1,nextRegion:t.region1===this.currentConnection.startRegion?t.region2:t.region1})}_step(){let t=this.candidateQueue.dequeue();if(!t)return this.failed=!0,void(this.error="Ran out of candidates");let e=this.visitedPointsForCurrentConnection.get(t.port.portId);for(;t&&void 0!==e&&!(t.g<e)&&(t=this.candidateQueue.dequeue(),t);)e=this.visitedPointsForCurrentConnection.get(t.port.portId);if(!t)return this.failed=!0,void(this.error="Ran out of candidates");if(this.lastCandidate=t,this.visitedPointsForCurrentConnection.set(t.port.portId,t.g),t.nextRegion===this.currentEndRegion)return this.processSolvedRoute(t),0===this.unprocessedConnections.length?void(this.solved=!0):void this.beginNewConnection();const n=this.getNextCandidates(t);for(const t of n)this.candidateQueue.enqueue(t)}};function xo(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function vo(t){return void 0===t}function bo(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function Po(...t){const e=(t,e)=>({a:t.a*e.a+t.c*e.b,c:t.a*e.c+t.c*e.d,e:t.a*e.e+t.c*e.f+t.e,b:t.b*e.a+t.d*e.b,d:t.b*e.c+t.d*e.d,f:t.b*e.e+t.d*e.f+t.f});switch((t=Array.isArray(t[0])?t[0]:t).length){case 0:throw new Error("no matrices provided");case 1:return t[0];case 2:return e(t[0],t[1]);default:{const[n,s,...o]=t;return Po(e(n,s),...o)}}}var{cos:So,sin:Mo,PI:No}=Math;var{tan:Io}=Math,_o=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t){const{bounds:t}=i.d;e=Math.min(e,t.minX),n=Math.max(n,t.maxX),s=Math.min(s,t.minY),o=Math.max(o,t.maxY)}return{minX:e,maxX:n,minY:s,maxY:o}},Co=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),To=(t,e)=>{const n=t.regions.map(t=>{const{bounds:n,center:s,...o}=t.d,i=[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.minX,y:n.maxY},{x:n.maxX,y:n.maxY}].map(t=>xo(e,t)),r={minX:Math.min(...i.map(t=>t.x)),maxX:Math.max(...i.map(t=>t.x)),minY:Math.min(...i.map(t=>t.y)),maxY:Math.max(...i.map(t=>t.y))},a=xo(e,s);return{...t,ports:[],d:{...o,bounds:r,center:a}}}),s=new Map;for(let e=0;e<t.regions.length;e++)s.set(t.regions[e],n[e]);const o=t.ports.map(t=>{const n=xo(e,t.d),o=s.get(t.region1),i=s.get(t.region2),r={...t,region1:o,region2:i,d:n};return o.ports.push(r),i.ports.push(r),r}),i=t.jumperLocations?.map(t=>{const n=xo(e,t.center),o=t.padRegions.map(t=>s.get(t)),i=xo(e,{x:1,y:0}),r=xo(e,{x:0,y:0}),a=i.x-r.x,c=i.y-r.y;return{center:n,orientation:Math.abs(c)>Math.abs(a)?"horizontal"===t.orientation?"vertical":"horizontal":t.orientation,padRegions:o}});return{regions:n,ports:o,...i&&{jumperLocations:i}}};function Eo(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function wo(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function Ro(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=t.x-e.x,r=t.y-e.y,a=s*s+o*o,c=a>0?(h=(i*s+r*o)/a,l=0,d=1,Math.max(l,Math.min(d,h))):0;var h,l,d;return{u:c,d2:Eo(t,{x:e.x+c*s,y:e.y+c*o})}}function Oo(t){const e=t.d.polygon;if(!e||e.length<3)return null;const n=t.d.polygonPerimeterCache;if(n)return n;const s=function(t){const e=t.length,n=new Array(e),s=new Array(e+1);s[0]=0;for(let o=0;o<e;o++){const i=t[o],r=t[(o+1)%e],a=Math.hypot(r.x-i.x,r.y-i.y);n[o]=a,s[o+1]=s[o]+a}return{edgeLengths:n,cumulative:s,perimeter:s[e]}}(e);return t.d.polygonPerimeterCache=s,s}function Ao(t){const e=Oo(t);if(e)return e.perimeter;const{minX:n,maxX:s,minY:o,maxY:i}=t.d.bounds;return 2*(s-n)+2*(i-o)}function zo(t,e){if(t.region1===e){if("number"==typeof t.region1T)return t.region1T;const n=Do(t.d,e);return t.region1T=n,n}if(t.region2===e){if("number"==typeof t.region2T)return t.region2T;const n=Do(t.d,e);return t.region2T=n,n}return Do(t.d,e)}function Do(t,e){const n=e.d.polygon;if(n&&n.length>=3){const s=Oo(e);if(s)return function(t,e,n,s=1e-6){let o=0,i=0,r=Number.POSITIVE_INFINITY;const a=s*s;for(let n=0;n<e.length;n++){const s=Ro(t,e[n],e[(n+1)%e.length]);if(s.d2<=a){o=n,i=s.u,r=s.d2;break}s.d2<r&&(o=n,i=s.u,r=s.d2)}return n.cumulative[o]+i*n.edgeLengths[o]}(t,n,s)}const{minX:s,maxX:o,minY:i,maxY:r}=e.d.bounds;return wo(t,s,o,i,r)}function Lo(t,e,n=1e-6){return Math.abs(t-e)<n}function Fo(t,e){return(t%e+e)%e}function Yo(t,e,n,s){const o=Math.abs(Fo(t-e,n));return o<s||n-o<s}function Xo(t,e,n,s,o){const i=Fo(t,s),r=Fo(e,s),a=Fo(n,s);return!(Math.abs(r-a)<o)&&(r<a?r<i&&i<a:i>r||i<a)}function ko(t,e,n){if("number"==typeof n&&n>0){let[s,o]=t,[i,r]=e;if(s=Fo(s,n),o=Fo(o,n),i=Fo(i,n),r=Fo(r,n),Yo(s,i,n,1e-6)||Yo(s,r,n,1e-6)||Yo(o,i,n,1e-6)||Yo(o,r,n,1e-6))return!1;return Xo(i,s,o,n,1e-12)!==Xo(r,s,o,n,1e-12)}const[s,o]=t[0]<t[1]?t:[t[1],t[0]],[i,r]=e[0]<e[1]?e:[e[1],e[0]];return!(Lo(s,i)||Lo(s,r)||Lo(o,i)||Lo(o,r))&&(s<i&&i<o&&o<r||i<s&&s<r&&r<o)}function $o(t,e){if(e.length<2)return 0;let n=1/0,s=-1/0,o=1/0,i=-1/0;for(const e of t.regions){const t=e;t.d?.bounds?(n=Math.min(n,t.d.bounds.minX),s=Math.max(s,t.d.bounds.maxX),o=Math.min(o,t.d.bounds.minY),i=Math.max(i,t.d.bounds.maxY)):t.d?.center&&(n=Math.min(n,t.d.center.x),s=Math.max(s,t.d.center.x),o=Math.min(o,t.d.center.y),i=Math.max(i,t.d.center.y))}const r=new Map;for(const e of t.regions){const t=e;t.d?.center&&r.set(e.regionId,t.d.center)}const a=[],c=2*(s-n)+2*(i-o);for(const t of e){let e,c;if("startRegion"in t&&t.startRegion){const n=t.startRegion,s=t.endRegion;e=n.d?.center,c=s.d?.center}else"startRegionId"in t&&(e=r.get(t.startRegionId),c=r.get(t.endRegionId));if(!e||!c)continue;const h=wo(e,n,s,o,i),l=wo(c,n,s,o,i);a.push([h,l])}let h=0;for(let t=0;t<a.length;t++)for(let e=t+1;e<a.length;e++)ko(a[t],a[e],c)&&h++;return h}var Bo=(t,e)=>{const n={arrows:[],circles:[],title:"Jumper Graph",lines:[],points:[],rects:[],texts:[],polygons:[],coordinateSystem:"cartesian"};for(const e of t.regions){const{bounds:t,isPad:s,isThroughJumper:o,isConnectionRegion:i,polygon:r}=e.d,a=(t.minX+t.maxX)/2,c=(t.minY+t.maxY)/2,h=t.maxX-t.minX,l=t.maxY-t.minY;let d;if(d=i?"rgba(255, 100, 255, 0.6)":o?"rgba(100, 200, 100, 0.5)":s?"rgba(255, 200, 100, 0.5)":"rgba(200, 200, 255, 0.1)",r&&r.length>=3){const t=r;n.polygons.push({points:t,fill:d})}else n.rects.push({center:{x:a,y:c},width:h-.1,height:l-.1,fill:d})}if(!e?.hidePortPoints)for(const e of t.ports){const t=e.region1.regionId.split(":").pop()??e.region1.regionId,s=e.region2.regionId.split(":").pop()??e.region2.regionId;n.circles.push({center:{x:e.d.x,y:e.d.y},radius:.05,fill:"rgba(128, 128, 128, 0.5)",label:`${t}-${s}`})}if(!e?.hideRegionPortLines)for(const e of t.ports){const t={x:(e.region1.d.bounds.minX+e.region1.d.bounds.maxX)/2,y:(e.region1.d.bounds.minY+e.region1.d.bounds.maxY)/2},s={x:(e.region2.d.bounds.minX+e.region2.d.bounds.maxX)/2,y:(e.region2.d.bounds.minY+e.region2.d.bounds.maxY)/2};n.lines.push({points:[t,{x:e.d.x,y:e.d.y},s],strokeColor:"rgba(100, 100, 100, 0.3)"})}if(e?.connections&&!e?.hideConnectionLines)for(const t of e.connections){const e=t.startRegion,s=t.endRegion,o={x:(e.d.bounds.minX+e.d.bounds.maxX)/2,y:(e.d.bounds.minY+e.d.bounds.maxY)/2},i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r=(o.x+i.x)/2,a=(o.y+i.y)/2;n.lines.push({points:[o,i],strokeColor:"rgba(255, 50, 150, 0.8)",strokeDash:"3 3"}),n.points.push({x:r,y:a,color:"rgba(200, 0, 100, 1)",label:t.connectionId})}return n},jo=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},Wo=.034685181009478865,Ho=0,Uo=4.072520483177124,Vo=0,Go=35.38577539020022,Zo=.5518001238069296,qo=class extends yo{getSolverName(){return"JumperGraphSolver"}UNIT_OF_COST="hops";portUsagePenalty=Wo;portUsagePenaltySq=Ho;crossingPenalty=Uo;crossingPenaltySq=Vo;ripCost=Go;baseMaxIterations=4e3;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Zo,rippingEnabled:!0,...t}),this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=$o(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}isTransitionAllowed(t,e,n){if(!t.d.isPad)return!0;const s=e=>{const n=e.region1===t?e.region2:e.region1;return Boolean(n.d.isThroughJumper)};return s(e)||s(n)}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isPad){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=Ao(t),o=[zo(e,t),zo(n,t)];let i=0;const r=t.assignments??[];for(const e of r)ko(o,[zo(e.regionPort1,t),zo(e.regionPort2,t)],s)&&i++;return i}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}getRipsRequiredForPortUsage(t,e,n){if(t.d.isPad){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=Ao(t),o=[zo(e,t),zo(n,t)],i=[],r=t.assignments??[];for(const e of r)ko(o,[zo(e.regionPort1,t),zo(e.regionPort2,t)],s)&&i.push(e);return i}(t,e,n),o=s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId);if(!t.d.isThroughJumper)return o;for(const e of t.assignments??[])e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId&&o.push(e);return o}isRipRequiredForPortUsage(t,e,n){if(!t.d.isThroughJumper&&!t.d.isPad)return!1;for(const e of t.assignments??[])if(e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)return!0;return!1}routeSolvedHook(t){}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=Bo(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;if(t.currentConnection&&!t.solved){const e=jo(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const t=jo(e.connection.connectionId),s=[];for(const t of e.path){const e=t.port;s.push({x:e.d.x,y:e.d.y})}s.length>0&&n.lines.push({points:s,strokeColor:t})}const s=t.candidateQueue.peekMany(10);for(let t=0;t<s.length;t++){const e=s[t],o=e.port,i=0===t;n.points.push({x:o.d.x,y:o.d.y,color:i?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const o=s[0];if(!t.solved&&o&&t.currentConnection){const e=jo(t.currentConnection.connectionId),s=[];let i=o;for(;i;){const t=i.port;s.unshift({x:t.d.x,y:t.d.y}),i=i.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}return n})(this)}},Jo=(t,e,n,s)=>{const o={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(o),n.ports.push(o),o},Ko=(t,e,n)=>{const s=.2;return{regionId:t,ports:[],d:{bounds:{minX:e-s,maxX:e+s,minY:n-s,maxY:n+s},center:{x:e,y:n},isPad:!1,isConnectionRegion:!0}}},Qo=.01,ti=(t,e,n)=>Math.max(e,Math.min(n,t)),ei=(t,e,n)=>"left"===e?Math.abs(t.x-n.minX)<Qo:"right"===e?Math.abs(t.x-n.maxX)<Qo:"top"===e?Math.abs(t.y-n.maxY)<Qo:Math.abs(t.y-n.minY)<Qo,ni=(t,e,n,s)=>{const o=s.x-n.x,i=s.y-n.y,r=t-n.x,a=e-n.y,c=o*o+i*i,h=c>0?ti((r*o+a*i)/c,0,1):0,l=n.x+h*o,d=n.y+h*i,u=t-l,p=e-d;return{x:l,y:d,d2:u*u+p*p}},si=(t,e,n,s,o)=>{const i=n.d.polygon;if(i&&i.length>=3){const n=new Set(o);let r=null;for(let a=0;a<i.length;a++){const c=i[a],h=i[(a+1)%i.length];if(o.length>0){if(!o.some(t=>ei(c,t,s)&&ei(h,t,s)&&n.has(t)))continue}const l=ni(t,e,c,h);(!r||l.d2<r.d2)&&(r=l)}if(r)return r}const r=n.d.bounds,a=[];if(o.length>0)for(const n of o)"left"===n?a.push({side:n,x:r.minX,y:ti(e,r.minY,r.maxY)}):"right"===n?a.push({side:n,x:r.maxX,y:ti(e,r.minY,r.maxY)}):"top"===n?a.push({side:n,x:ti(t,r.minX,r.maxX),y:r.maxY}):a.push({side:n,x:ti(t,r.minX,r.maxX),y:r.minY});0===a.length&&a.push({side:"left",x:r.minX,y:ti(e,r.minY,r.maxY)},{side:"right",x:r.maxX,y:ti(e,r.minY,r.maxY)},{side:"top",x:ti(t,r.minX,r.maxX),y:r.maxY},{side:"bottom",x:ti(t,r.minX,r.maxX),y:r.minY});let c=null;for(const n of a){if(o.length>0&&!o.includes(n.side))continue;const s=t-n.x,i=e-n.y,r=s*s+i*i;(!c||r<c.d2)&&(c={x:n.x,y:n.y,d2:r})}return c},oi=(t,e,n,s)=>{const o=((t,e,n)=>{const s=[];return Math.abs(t-n.minX)<Qo&&s.push("left"),Math.abs(t-n.maxX)<Qo&&s.push("right"),Math.abs(e-n.maxY)<Qo&&s.push("top"),Math.abs(e-n.minY)<Qo&&s.push("bottom"),s})(t,e,s);let i=null,r=Number.POSITIVE_INFINITY,a={x:t,y:e};for(const c of n){if(c.d.isPad||c.d.isThroughJumper)continue;const n=c.d.bounds;if(!(Math.abs(n.minX-s.minX)<.01||Math.abs(n.maxX-s.maxX)<.01||Math.abs(n.minY-s.minY)<.01||Math.abs(n.maxY-s.maxY)<.01))continue;const h=si(t,e,c,s,o);if(!h)continue;const l=Math.sqrt(h.d2);l<r&&(r=l,i=c,a={x:h.x,y:h.y})}return i?{region:i,portPosition:a}:null},ii={padWidth:.8,outerPadHeight:.5,innerPadHeight:.4,leftPadCenterX:-.9,rightPadCenterX:.9,row1CenterY:-1.2,row2CenterY:-.4,row3CenterY:.4,row4CenterY:1.2},ri=({cols:t,rows:e,marginX:n,marginY:s,innerColChannelPointCount:o=1,innerRowChannelPointCount:i=1,regionsBetweenPads:r=!1,outerPaddingX:a=.5,outerPaddingY:c=.5,outerChannelXPointCount:h,outerChannelYPointCount:l,orientation:d="vertical",center:u,bounds:p,parallelTracesUnderJumperCount:f=2})=>{const m=[],g=[],{padWidth:y,outerPadHeight:x,innerPadHeight:v,leftPadCenterX:b,rightPadCenterX:P,row1CenterY:S,row2CenterY:M,row3CenterY:N,row4CenterY:I}=ii,_=y/2,C=x/2,T=v/2,E=P-b+y,w=E+n,R=I-S+x,O=R+s;let A=a,z=c;if(p){const o=t*E+(t-1)*n,i=e*R+(e-1)*s;A=(("horizontal"===d?p.maxY-p.minY:p.maxX-p.minX)-o)/2,z=(("horizontal"===d?p.maxX-p.minX:p.maxY-p.minY)-i)/2}const D=h??Math.max(1,Math.floor(A/.4)),L=l??Math.max(1,Math.floor(z/.4)),F=[],Y=[],X=(t,e,n,s)=>({regionId:t,ports:[],d:{bounds:e,center:Co(e),isPad:n,isThroughJumper:s}}),k=(t,e,n)=>{const s=e.d.bounds,o=n.d.bounds;let i,r;Math.abs(s.maxX-o.minX)<.001?(i=s.maxX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.minX-o.maxX)<.001?(i=s.minX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.maxY-o.minY)<.001?(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.maxY):(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.minY);const a={portId:t,region1:e,region2:n,d:{x:i,y:r}};return e.ports.push(a),n.ports.push(a),a},$=(t,e,n,s)=>{if(s<=0)return[];if(1===s)return[k(t,e,n)];const o=e.d.bounds,i=n.d.bounds,r=[];let a,c,h,l;Math.abs(o.maxX-i.minX)<.001?(a=!0,c=o.maxX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.minX-i.maxX)<.001?(a=!0,c=o.minX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.maxY-i.minY)<.001?(a=!1,c=o.maxY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX)):(a=!1,c=o.minY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX));for(let o=0;o<s;o++){const i=h+(o+.5)/s*(l-h),d={portId:`${t}:${o}`,region1:e,region2:n,d:{x:a?c:i,y:a?i:c}};e.ports.push(d),n.ports.push(d),r.push(d)}return r};for(let n=0;n<e;n++){F[n]=[];for(let a=0;a<t;a++){const c=`cell_${n}_${a}`,h=a*w,l=-n*O,d=h+b,u=l+S,p=h+b,y=l+M,x=h+b,v=l+N,E=h+b,R=l+I,B=h+P,j=l+I,W=h+P,H=l+N,U=h+P,V=l+M,G=h+P,Z=l+S,q=(t,e,n)=>({minX:t-_,maxX:t+_,minY:e-n,maxY:e+n}),J=q(d,u,C),K=q(p,y,T),Q=q(x,v,T),tt=q(E,R,C),et=q(B,j,C),nt=q(W,H,T),st=q(U,V,T),ot=q(G,Z,C),it={minX:J.maxX,maxX:ot.minX,minY:J.minY,maxY:tt.maxY},rt=.3,at={minX:d,maxX:G,minY:u-rt/2,maxY:u+rt/2},ct={minX:p,maxX:U,minY:y-rt/2,maxY:y+rt/2},ht={minX:x,maxX:W,minY:v-rt/2,maxY:v+rt/2},lt={minX:E,maxX:B,minY:R-rt/2,maxY:R+rt/2},dt=J.minX,ut=ot.maxX,pt=J.minY,ft=tt.maxY,mt=X(`${c}:pad1`,J,!0),gt=X(`${c}:pad2`,K,!0),yt=X(`${c}:pad3`,Q,!0),xt=X(`${c}:pad4`,tt,!0),vt=X(`${c}:pad5`,et,!0),bt=X(`${c}:pad6`,nt,!0),Pt=X(`${c}:pad7`,st,!0),St=X(`${c}:pad8`,ot,!0),Mt=X(`${c}:underjumper`,it,!1),Nt=X(`${c}:throughjumper1`,at,!1,!0),It=X(`${c}:throughjumper2`,ct,!1,!0),_t=X(`${c}:throughjumper3`,ht,!1,!0),Ct=X(`${c}:throughjumper4`,lt,!1,!0);m.push(mt,gt,yt,xt,vt,bt,Pt,St,Mt,Nt,It,_t,Ct);const Tt=(d+G)/2,Et=(u+R)/2;Y.push({center:{x:Tt,y:Et},orientation:"vertical",padRegions:[mt,gt,yt,xt,vt,bt,Pt,St]});let wt=null,Rt=null,Ot=null,At=null,zt=null,Dt=null;r&&(wt=X(`${c}:L-BP12`,{minX:J.minX,maxX:J.maxX,minY:J.maxY,maxY:K.minY},!1),Rt=X(`${c}:L-BP23`,{minX:K.minX,maxX:K.maxX,minY:K.maxY,maxY:Q.minY},!1),Ot=X(`${c}:L-BP34`,{minX:Q.minX,maxX:Q.maxX,minY:Q.maxY,maxY:tt.minY},!1),At=X(`${c}:R-BP87`,{minX:ot.minX,maxX:ot.maxX,minY:ot.maxY,maxY:st.minY},!1),zt=X(`${c}:R-BP76`,{minX:st.minX,maxX:st.maxX,minY:st.maxY,maxY:nt.minY},!1),Dt=X(`${c}:R-BP65`,{minX:nt.minX,maxX:nt.maxX,minY:nt.maxY,maxY:et.minY},!1),m.push(wt,Rt,Ot,At,zt,Dt));const Lt=0===a,Ft=n===e-1,Yt=a===t-1;let Xt;if(Yt)Xt=ut+A;else{Xt=(a+1)*w+b-_}let kt=null;0===n&&(kt=X(`${c}:T`,{minX:Lt?dt-A:dt,maxX:Xt,minY:ft,maxY:ft+z},!1),m.push(kt));let $t=null;$t=X(`${c}:B`,{minX:Lt?dt-A:dt,maxX:Xt,minY:pt-(Ft?z:s),maxY:pt},!1),m.push($t);let Bt=null;Lt&&(Bt=X(`${c}:L`,{minX:dt-A,maxX:dt,minY:pt,maxY:ft},!1),m.push(Bt));const jt=X(`${c}:R`,{minX:ut,maxX:Xt,minY:pt,maxY:ft},!1);if(m.push(jt),F[n][a]={pad1:mt,pad2:gt,pad3:yt,pad4:xt,pad5:vt,pad6:bt,pad7:Pt,pad8:St,underjumper:Mt,throughjumper1:Nt,throughjumper2:It,throughjumper3:_t,throughjumper4:Ct,top:kt,bottom:$t,left:Bt,right:jt,leftBP12:wt,leftBP23:Rt,leftBP34:Ot,rightBP87:At,rightBP76:zt,rightBP65:Dt},kt)if(Bt&&g.push(...$(`${c}:T-L`,kt,Bt,D)),g.push(...$(`${c}:T-R`,kt,jt,Yt?D:o)),g.push(k(`${c}:T-P4`,kt,xt)),g.push(k(`${c}:T-P5`,kt,vt)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:T-UJ${n}`,region1:kt,region2:Mt,d:{x:t.minX+e*n,y:t.maxY}};kt.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:T-UJ`,kt,Mt));if($t)if(Bt&&g.push(...$(`${c}:B-L`,$t,Bt,D)),g.push(...$(`${c}:B-R`,$t,jt,Yt?D:o)),g.push(k(`${c}:B-P1`,$t,mt)),g.push(k(`${c}:B-P8`,$t,St)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:B-UJ${n}`,region1:$t,region2:Mt,d:{x:t.minX+e*n,y:t.minY}};$t.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:B-UJ`,$t,Mt));Bt&&(g.push(k(`${c}:L-P1`,Bt,mt)),g.push(k(`${c}:L-P2`,Bt,gt)),g.push(k(`${c}:L-P3`,Bt,yt)),g.push(k(`${c}:L-P4`,Bt,xt))),g.push(k(`${c}:R-P5`,jt,vt)),g.push(k(`${c}:R-P6`,jt,bt)),g.push(k(`${c}:R-P7`,jt,Pt)),g.push(k(`${c}:R-P8`,jt,St)),r&&(Bt&&(g.push(k(`${c}:L-BP12`,Bt,wt)),g.push(k(`${c}:L-BP23`,Bt,Rt)),g.push(k(`${c}:L-BP34`,Bt,Ot))),g.push(k(`${c}:UJ-LBP12`,wt,Mt)),g.push(k(`${c}:UJ-LBP23`,Rt,Mt)),g.push(k(`${c}:UJ-LBP34`,Ot,Mt)),g.push(k(`${c}:R-BP87`,jt,At)),g.push(k(`${c}:R-BP76`,jt,zt)),g.push(k(`${c}:R-BP65`,jt,Dt)),g.push(k(`${c}:UJ-RBP87`,At,Mt)),g.push(k(`${c}:UJ-RBP76`,zt,Mt)),g.push(k(`${c}:UJ-RBP65`,Dt,Mt)));const Wt={portId:`${c}:TJ1-P1`,region1:Nt,region2:mt,d:{x:d,y:u}};Nt.ports.push(Wt),mt.ports.push(Wt),g.push(Wt);const Ht={portId:`${c}:TJ1-P8`,region1:Nt,region2:St,d:{x:G,y:Z}};Nt.ports.push(Ht),St.ports.push(Ht),g.push(Ht);const Ut={portId:`${c}:TJ2-P2`,region1:It,region2:gt,d:{x:p,y:y}};It.ports.push(Ut),gt.ports.push(Ut),g.push(Ut);const Vt={portId:`${c}:TJ2-P7`,region1:It,region2:Pt,d:{x:U,y:V}};It.ports.push(Vt),Pt.ports.push(Vt),g.push(Vt);const Gt={portId:`${c}:TJ3-P3`,region1:_t,region2:yt,d:{x:x,y:v}};_t.ports.push(Gt),yt.ports.push(Gt),g.push(Gt);const Zt={portId:`${c}:TJ3-P6`,region1:_t,region2:bt,d:{x:W,y:H}};_t.ports.push(Zt),bt.ports.push(Zt),g.push(Zt);const qt={portId:`${c}:TJ4-P4`,region1:Ct,region2:xt,d:{x:E,y:R}};Ct.ports.push(qt),xt.ports.push(qt),g.push(qt);const Jt={portId:`${c}:TJ4-P5`,region1:Ct,region2:vt,d:{x:B,y:j}};if(Ct.ports.push(Jt),vt.ports.push(Jt),g.push(Jt),a>0){const t=F[n][a-1];g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P1`,t.right,mt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P2`,t.right,gt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P3`,t.right,yt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P4`,t.right,xt)),r&&(g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP12`,t.right,wt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP23`,t.right,Rt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP34`,t.right,Ot))),kt&&t.top&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:T-T`,t.top,kt,L)),$t&&t.bottom&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:B-B`,t.bottom,$t,Ft?L:i))}if(n>0){const t=F[n-1][a];if(Bt&&g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-L`,t.bottom,Bt,D)),g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P4`,t.bottom,xt)),r){const e=Mt.d.bounds,s=(e.maxX-e.minX)/(f+1);for(let o=1;o<=f;o++){const i=e.minX+s*o,r={portId:`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ${o}`,region1:t.bottom,region2:Mt,d:{x:i,y:e.maxY}};t.bottom.ports.push(r),Mt.ports.push(r),g.push(r)}}else g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ`,t.bottom,Mt));g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P5`,t.bottom,vt)),g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-R`,t.bottom,jt,Yt?D:o))}}}let B={regions:m,ports:g,jumperLocations:Y};const j="horizontal"===d;if(j||void 0!==u||void 0!==p){const t=_o(B.regions),e=Co(t),n=[];let s;s=u||(p?Co(p):e),n.push(bo(s.x,s.y)),j&&n.push(function(t,e,n){const s=So(t),o=Mo(t),i={a:s,c:-o,e:0,b:o,d:s,f:0};return vo(e)||vo(n)?i:Po([bo(e,n),i,bo(-e,-n)])}(-Math.PI/2)),n.push(bo(-e.x,-e.y));const o=function(...t){return Po(...t)}(...n);B=To(B,o)}return B},ai={viasByNet:{net1:[{viaId:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",diameter:.3,position:{x:.815244,y:-.055081}},{viaId:"8a898812-db2b-4b81-899d-f953b3222f9a",diameter:.3,position:{x:-.528763,y:.676055}}],net3:[{viaId:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",diameter:.3,position:{x:-.808222,y:-.726499}},{viaId:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",diameter:.3,position:{x:.901143,y:.437488}}],net4:[{viaId:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",diameter:.3,position:{x:-.029,y:.691542}},{viaId:"37a70467-7553-415f-8ad7-8b88a5e56ca8",diameter:.3,position:{x:-.824388,y:.272808}},{viaId:"6d182b7d-a260-427b-8c43-a09409422252",diameter:.3,position:{x:.083422,y:-.705274}}],net5:[{viaId:"346c301a-f2b4-44d7-b975-5438ddaa0bde",diameter:.3,position:{x:.517145,y:-.456503}},{viaId:"c54b4b94-90e0-4240-97ef-883cf097d79d",diameter:.3,position:{x:.471002,y:.692404}},{viaId:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",diameter:.3,position:{x:-.833162,y:-.227118}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",toPort:"8a898812-db2b-4b81-899d-f953b3222f9a",layer:"bottom",segments:[{x:.815244,y:-.055081},{x:1.01282,y:-.252657},{x:1.01282,y:-.563283},{x:.444829,y:-1.131274},{x:-.093033,y:-1.131274},{x:-.382222,y:-.842085},{x:-.382222,y:.433097},{x:-.528763,y:.579638},{x:-.528763,y:.676055}]},{routeId:"net3:route_0",fromPort:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",toPort:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",layer:"bottom",segments:[{x:-.808222,y:-.726499},{x:-.808222,y:-.912474},{x:-.238422,y:-1.482274},{x:.590217,y:-1.482274},{x:1.36382,y:-.708672},{x:1.36382,y:-.001202},{x:.92513,y:.437488},{x:.901143,y:.437488}]},{routeId:"net4:route_0",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"6d182b7d-a260-427b-8c43-a09409422252",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:-.592852},{x:.083422,y:-.705274}]},{routeId:"net4:route_1",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"37a70467-7553-415f-8ad7-8b88a5e56ca8",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:.778747},{x:-.352308,y:1.102055},{x:-.705218,y:1.102055},{x:-.954763,y:.85251},{x:-.954763,y:.403183},{x:-.824388,y:.272808}]},{routeId:"net5:route_0",fromPort:"346c301a-f2b4-44d7-b975-5438ddaa0bde",toPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",layer:"bottom",segments:[{x:.517145,y:-.456503},{x:.389244,y:-.328602},{x:.389244,y:.610646},{x:.471002,y:.692404}]},{routeId:"net5:route_1",fromPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",toPort:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",layer:"bottom",segments:[{x:.471002,y:.692404},{x:.471002,y:1.111132},{x:.129079,y:1.453055},{x:-.850606,y:1.453055},{x:-1.305763,y:.997899},{x:-1.305763,y:.151728},{x:-.926917,y:-.227118},{x:-.833162,y:-.227118}]}],tileWidth:2.9695829999999996,tileHeight:3.2353289999999997};function ci(t,e,n,s,o,i,r){return!!ko(t,e,n)||function(t,e,n,s,o=1e-9){const i=(t,e)=>Math.abs(t.x-e.x)<o&&Math.abs(t.y-e.y)<o;if(i(t,n)||i(t,s)||i(e,n)||i(e,s))return!1;const r=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),a=r(n,s,t),c=r(n,s,e),h=r(t,e,n),l=r(t,e,s);if(a*c<0&&h*l<0)return!0;const d=(t,e,n,s)=>{if(Math.abs(s)>o)return!1;const i=Math.min(e.x,n.x)-o,r=Math.max(e.x,n.x)+o,a=Math.min(e.y,n.y)-o,c=Math.max(e.y,n.y)+o;return t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c};return!((!d(t,n,s,a)||i(t,n)||i(t,s))&&(!d(e,n,s,c)||i(e,n)||i(e,s))&&(!d(n,t,e,h)||i(n,t)||i(n,e))&&(!d(s,t,e,l)||i(s,t)||i(s,e)))}(s.d,o.d,i.d,r.d)}var hi=1e-6;function li(t,e){return Math.abs(t.x-e.x)<=hi&&Math.abs(t.y-e.y)<=hi}function di(t,e){const n=t[t.length-1];n&&li(n,e)||t.push(e)}function ui(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=Math.hypot(t,i);r<s&&(s=r,n=o)}return n}function pi(t,e){const n=new Set(e.map(t=>t.viaId));return t.routeSegments.filter(t=>"bottom"===t.layer&&n.has(t.fromPort)&&n.has(t.toPort)&&t.segments.length>=2)}function fi(t,e){const n=function(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=function(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}function mi(t,e,n){const s=function(t){const e=[];for(const n of t)di(e,n);return e}(e);if(s.length<2)return;const o=t[t.length-1];if(!o||o.layer!==n)return void t.push({points:s,layer:n});const i=o.points[o.points.length-1],r=s[0];if(!i||!r||!li(i,r))return void t.push({points:s,layer:n});const a=s.slice(1);for(const t of a)di(o.points,t)}function gi(t,e){if(0===t.path.length)return[];const n=t.path,s=[],o=new Set;for(let t=1;t<n.length;t++){const i=n[t-1],r=n[t],a={x:i.port.d.x,y:i.port.d.y},c={x:r.port.d.x,y:r.port.d.y},h=r.lastRegion;if(!(!!e&&!!h?.d?.isViaRegion)){mi(s,[a,c],"top");continue}const l=fi(e,h);if(0===l.length)continue;const d=ui(l,a),u=ui(l,c);d&&mi(s,[a,d.position],"top");const p=pi(e,l);if(p.length>0&&!o.has(h.regionId)){o.add(h.regionId);for(const t of p)mi(s,t.segments,"bottom")}u&&mi(s,[u.position,c],"top")}return s}function yi(t,e){return function(t){const e=[];for(const n of t)for(const t of n.points)di(e,t);return e}(gi(t,e))}var xi=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},vi=["rgba(231, 76, 60, 0.35)","rgba(46, 204, 113, 0.35)","rgba(52, 152, 219, 0.35)","rgba(243, 156, 18, 0.35)","rgba(155, 89, 182, 0.35)","rgba(26, 188, 156, 0.35)","rgba(241, 196, 15, 0.35)","rgba(230, 126, 34, 0.35)"],bi=.034685181009478865,Pi=0,Si=4.072520483177124,Mi=0,Ni=35.38577539020022,Ii=.5518001238069296,_i=class extends yo{getSolverName(){return"ViaGraphSolver"}UNIT_OF_COST="hops";viaTile;portUsagePenalty=bi;portUsagePenaltySq=Pi;crossingPenalty=Si;crossingPenaltySq=Mi;ripCost=Ni;baseMaxIterations=9e5;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Ii,rippingEnabled:!0,...t}),this.viaTile=t.viaTile,this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=$o(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isViaRegion){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return 0;const o=Ao(t),i=[zo(e,t),zo(n,t)];let r=0;const a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;ci(i,[zo(a,t),zo(c,t)],o,e,n,a,c)&&r++}return r}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}isRipRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).some(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}return!1}getRipsRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return[];const o=Ao(t),i=[zo(e,t),zo(n,t)],r=[],a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;ci(i,[zo(a,t),zo(c,t)],o,e,n,a,c)&&r.push(s)}return r}(t,e,n);return s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}routeSolvedHook(t){}getSolvedRoutePoints(t){return yi(t,this.viaTile)}getSolvedRouteLineSegments(t){return gi(t,this.viaTile)}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=Bo(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;const s=new Set(["T","B","L","R"]);let o=0;const i=new Map;let r=0;for(const t of e.regions){const e=t;if(!(e.d.polygon&&e.d.polygon.length>=3))continue;const a=e.regionId.split(":").pop()??"";s.has(a)||e.d.isConnectionRegion||(i.has(a)||(i.set(a,vi[o%vi.length]),o++),n.polygons[r]&&(n.polygons[r].fill=i.get(a))),r++}if(t.currentConnection&&!t.solved){const e=xi(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const s=xi(e.connection.connectionId),o=t.getSolvedRouteLineSegments(e);for(const t of o){const e="bottom"===t.layer;n.lines.push({points:t.points,strokeColor:e?"rgba(52, 152, 219, 0.95)":s,...e?{strokeDash:"3 2"}:{}})}}const a=t.candidateQueue.peekMany(10);for(let t=0;t<a.length;t++){const e=a[t],s=e.port,o=0===t;n.points.push({x:s.d.x,y:s.d.y,color:o?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const c=a[0];if(!t.solved&&c&&t.currentConnection){const e=xi(t.currentConnection.connectionId),s=[];let o=c;for(;o;){const t=o.port;s.unshift({x:t.d.x,y:t.d.y}),o=o.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}if(t.viaTile){n.circles||(n.circles=[]);for(const[e,s]of Object.entries(t.viaTile.viasByNet)){const t=i.get(e),o=t?t.replace("0.35","0.5"):"rgba(255, 0, 0, 0.3)";for(const t of s)n.circles.push({center:t.position,radius:t.diameter/2,fill:o,label:e})}}return n})(this)}};function Ci(t,e){let n=1/0,s={x:t.x,y:t.y};for(let o=0;o<e.length;o++){const i=e[o],r=e[(o+1)%e.length],a=r.x-i.x,c=r.y-i.y,h=a*a+c*c;if(h<1e-10)continue;const l=Math.max(0,Math.min(1,((t.x-i.x)*a+(t.y-i.y)*c)/h)),d=i.x+l*a,u=i.y+l*c,p=Math.sqrt((t.x-d)**2+(t.y-u)**2);p<n&&(n=p,s={x:d,y:u})}return{...s,dist:n}}var Ti=t=>{const{x:e,y:n,regions:s}=t,o=s.some(t=>t.regionId.startsWith("filler:"));let i=null,r=1/0,a={x:e,y:n};for(const t of s){if(t.d.isPad||t.d.isThroughJumper||t.d.isConnectionRegion)continue;if(o&&!t.regionId.startsWith("filler:"))continue;const s=t.d.polygon;if(!s||s.length<3)continue;const c=Ci({x:e,y:n},s);c.dist<r&&(r=c.dist,i=t,a={x:c.x,y:c.y})}return i?{region:i,portPosition:a}:null},Ei=!0,wi={CCW:-1,CW:1,NOT_ORIENTABLE:0},Ri=2*Math.PI,Oi=Object.freeze({__proto__:null,BOUNDARY:2,CCW:Ei,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:wi,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:Ri,START_VERTEX:1}),Ai=1e-6;function zi(t){Ai=t}function Di(){return Ai}function Li(t){return t<Ai&&t>-Ai}function Fi(t,e){return t-e<Ai&&t-e>-Ai}function Yi(t,e){return t-e>Ai}function Xi(t,e){return t-e<-Ai}var ki={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:Fi,EQ_0:Li,GE:function(t,e){return t-e>-Ai},GT:Yi,LE:function(t,e){return t-e<Ai},LT:Xi,getTolerance:Di,setTolerance:zi}),Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let t in Oi)ki[t]=Oi[t];Object.defineProperty(ki,"DP_TOL",{get:function(){return Di()},set:function(t){zi(t)}});var $i=class{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}};ki.Errors=$i;var Bi=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:void 0===t})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],s=t||this.first,o=e||this.last,i=s;if(void 0===i)return n;do{n.push(i),i=i.next}while(i!==o.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(null==e)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw $i.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},ji={stroke:"black"},Wi=class{constructor(t=ji){for(const e in t)this[e]=t[e];this.stroke=t.stroke??ji.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(void 0!==this[e]?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n="className"===t?"class":this.convertCamelToKebabCase(t);return null===e?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}};function Hi(t){return new Wi(t).toAttributesString()}function Ui(t,e){let n=[],[s,o,i]=t.standard,[r,a,c]=e.standard,h=s*a-o*r,l=i*a-o*c,d=s*c-i*r;if(!ki.Utils.EQ_0(h)){let t,e;0===o?(t=i/s,e=d/h):0===a?(t=c/r,e=d/h):0===s?(t=l/h,e=i/o):0===r?(t=l/h,e=c/a):(t=l/h,e=d/h),n.push(new ki.Point(t,e))}return n}function Vi(t,e){let n=[],s=e.pc.projectionOn(t),o=e.pc.distanceTo(s)[0];if(ki.Utils.EQ(o,e.r))n.push(s);else if(ki.Utils.LT(o,e.r)){let i,r,a=Math.sqrt(e.r*e.r-o*o);i=t.norm.rotate90CCW().multiply(a),r=s.translate(i),n.push(r),i=t.norm.rotate90CW().multiply(a),r=s.translate(i),n.push(r)}return n}function Gi(t,e){let n=[];for(let s of e.toSegments()){let e=qi(s,t);for(let t of e)fr(t,n)||n.push(t)}return n}function Zi(t,e){let n=[];if(0===Gi(t,e.box).length)return n;let s=Vi(t,new ki.Circle(e.pc,e.r));for(let t of s)t.on(e)&&n.push(t);return n}function qi(t,e){let n=[];return t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&!t.isZeroLength()&&n.push(t.pe),n.length>0||t.isZeroLength()||t.ps.leftTo(e)&&t.pe.leftTo(e)||!t.ps.leftTo(e)&&!t.pe.leftTo(e)?n:Ui(new ki.Line(t.ps,t.pe),e)}function Ji(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)&&n.push(e.ps),n;let s=new ki.Line(t.ps,t.pe),o=new ki.Line(e.ps,e.pe);if(s.incidentTo(o))t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&n.push(t.pe),!e.ps.on(t)||e.ps.equalTo(t.ps)||e.ps.equalTo(t.pe)||n.push(e.ps),!e.pe.on(t)||e.pe.equalTo(t.ps)||e.pe.equalTo(t.pe)||n.push(e.pe);else{let i=Ui(s,o);i.length>0&&Ki(i[0],t)&&Ki(i[0],e)&&n.push(i[0])}return n}function Ki(t,e){const n=e.box;return ki.Utils.LE(t.x,n.xmax)&&ki.Utils.GE(t.x,n.xmin)&&ki.Utils.LE(t.y,n.ymax)&&ki.Utils.GE(t.y,n.ymin)}function Qi(t,e){let n=[];if(t.isZeroLength()){let[s,o]=t.ps.distanceTo(e.pc);return ki.Utils.EQ(s,e.r)&&n.push(t.ps),n}let s=Vi(new ki.Line(t.ps,t.pe),e);for(let e of s)e.on(t)&&n.push(e);return n}function tr(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let s=Vi(new ki.Line(t.ps,t.pe),new ki.Circle(e.pc,e.r));for(let o of s)o.on(t)&&o.on(e)&&n.push(o);return n}function er(t,e){let n=[],s=new ki.Vector(t.pc,e.pc),o=t.r,i=e.r;if(ki.Utils.EQ_0(o)||ki.Utils.EQ_0(i))return n;if(ki.Utils.EQ_0(s.x)&&ki.Utils.EQ_0(s.y)&&ki.Utils.EQ(o,i))return n.push(t.pc.translate(-o,0)),n;let r,a=t.pc.distanceTo(e.pc)[0];if(ki.Utils.GT(a,o+i))return n;if(ki.Utils.LT(a,Math.abs(o-i)))return n;if(s.x/=a,s.y/=a,ki.Utils.EQ(a,o+i)||ki.Utils.EQ(a,Math.abs(o-i)))return r=t.pc.translate(o*s.x,o*s.y),n.push(r),n;let c=o*o/(2*a)-i*i/(2*a)+a/2,h=t.pc.translate(c*s.x,c*s.y),l=Math.sqrt(o*o-c*c);return r=h.translate(s.rotate90CCW().multiply(l)),n.push(r),r=h.translate(s.rotate90CW().multiply(l)),n.push(r),n}function nr(t,e){let n=[];if(t.pc.equalTo(e.pc)&&ki.Utils.EQ(t.r,e.r)){let s;return s=t.start,s.on(e)&&n.push(s),s=t.end,s.on(e)&&n.push(s),s=e.start,s.on(t)&&n.push(s),s=e.end,s.on(t)&&n.push(s),n}let s=new ki.Circle(t.pc,t.r),o=new ki.Circle(e.pc,e.r),i=s.intersect(o);for(let s of i)s.on(t)&&s.on(e)&&n.push(s);return n}function sr(t,e){let n=[];if(e.pc.equalTo(t.pc)&&ki.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let s=er(e,new ki.Circle(t.pc,t.r));for(let e of s)e.on(t)&&n.push(e);return n}function or(t,e){return t.isSegment?Ji(t.shape,e):tr(e,t.shape)}function ir(t,e){return t.isSegment?tr(t.shape,e):nr(t.shape,e)}function rr(t,e){return t.isSegment?qi(t.shape,e):Zi(e,t.shape)}function ar(t,e){return t.isSegment?Qi(t.shape,e):sr(t.shape,e)}function cr(t,e){let n=[];for(let s of e.edges)for(let e of or(s,t))n.push(e);return n}function hr(t,e){let n=[];for(let s of e.edges)for(let e of ir(s,t))n.push(e);return n}function lr(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of rr(s,t))fr(e,n)||n.push(e);return t.sortPoints(n)}function dr(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of ar(s,t))n.push(e);return n}function ur(t,e){return t.isSegment?or(e,t.shape):t.isArc?ir(e,t.shape):t.isLine?rr(e,t.shape):t.isRay?(n=e,s=t.shape,n.isSegment?gr(s,n.shape):yr(s,n.shape)):[];var n,s}function pr(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let s=e.edges.search(t.shape.box);for(let e of s)n=[...n,...ur(t,e)];return n}function fr(t,e){return e.some(e=>e.equalTo(t))}function mr(t){return new ki.Line(t.start,t.norm)}function gr(t,e){return qi(e,mr(t)).filter(e=>t.contains(e))}function yr(t,e){return Zi(mr(t),e).filter(e=>t.contains(e))}function xr(t,e){return Vi(mr(t),e).filter(e=>t.contains(e))}function vr(t,e){return Ui(mr(t),e).filter(e=>t.contains(e))}function br(t,e){return lr(mr(t),e).filter(e=>t.contains(e))}function Pr(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw $i.UNSUPPORTED_SHAPE_TYPE}function Sr(t,e){let n=[];for(let s of e)n=[...n,...Pr(t,s.shape)];return n}var Mr=class t extends Bi{constructor(...t){if(super(),this.isInfinite=!1,1===t.length&&t[0]instanceof Array&&t[0].length>0){const e=t[0],n=e.length,s=t=>t instanceof ki.Segment||t instanceof ki.Arc||t instanceof ki.Ray,o=t=>t instanceof ki.Segment||t instanceof ki.Arc;if(!(1===n&&(t=>t instanceof ki.Segment||t instanceof ki.Arc||t instanceof ki.Ray||t instanceof ki.Line)(e[0])||n>1&&s(e[0])&&s(e[n-1])&&e.slice(1,n-1).every(o)))throw ki.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof ki.Ray||t instanceof ki.Line);for(let t of e){let e=new ki.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new ki.Box)}get vertices(){let t=this.edges.map(t=>t.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let e of this)t+=e.length;return t}clone(){return new t(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new ki.Edge(n[0]),o=e.prev;return this.insert(s,o),e.shape=n[1],s}getChain(t,e){let n=[];for(let s=t;s!==e.next;s=s.next)n.push(s);return n}split(t){for(let e of t){let t=this.findEdgeByPoint(e);this.addVertex(e,t)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}distanceTo(t){if(t instanceof Point){const[e,n]=ki.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ki.Line){const[e,n]=ki.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ki.Circle){const[e,n]=ki.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ki.Segment){const[e,n]=ki.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ki.Arc){const[e,n]=ki.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof ki.Multiline)return ki.Distance.multiline2multiline(this,t);throw ki.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof ki.Multiline?function(t,e){let n=[];for(let s of t)for(let t of e)n=[...n,...Pr(s.shape,t.shape)];return n}(this,t):Sr(t,this)}contains(t){if(t instanceof ki.Point)return this.edges.some(e=>e.shape.contains(t));throw ki.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new ki.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new ki.Matrix){return new t(this.edges.map(t=>t.shape.transform(e)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t}svg(t={}){let e=`\n<path ${Hi({fill:"none",...t})} d="`;e+=`\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='" >\n</path>',e}};ki.Multiline=Mr;function Nr(t,e,n){let s=n.length,o=t.shape.split(e);if(0===o.length)return;let i=0;i=null===o[0]?0:null===o[1]?t.shape.length:o[0].length;let r,a=0;Fi(i,0)&&(a|=1),Fi(i,t.shape.length)&&(a|=2),r=i===1/0?o[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+i,n.push({id:s,pt:e,arc_length:r,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function Ir(t){t.int_points1_sorted=_r(t.int_points1),t.int_points2_sorted=_r(t.int_points2)}function _r(t){let e=new Map,n=0;for(let s of t)e.has(s.face)||(e.set(s.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(Cr)}function Cr(t,e){return t.faceId<e.faceId?-1:t.faceId>e.faceId?1:t.arc_length<e.arc_length?-1:t.arc_length>e.arc_length?1:0}function Tr(t){if(t.int_points1.length<2)return;let e,n,s,o,i=!1;for(let r=0;r<t.int_points1_sorted.length;r++)if(-1!==t.int_points1_sorted[r].id){e=t.int_points1_sorted[r],n=t.int_points2[e.id];for(let a=r+1;a<t.int_points1_sorted.length&&(s=t.int_points1_sorted[a],Fi(s.arc_length,e.arc_length));a++)-1!==s.id&&(o=t.int_points2[s.id],-1!==o.id&&s.edge_before===e.edge_before&&s.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(s.id=-1,o.id=-1,i=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let s=1;s<t.int_points2_sorted.length;s++){let o=t.int_points2_sorted[s];if(-1===o.id)continue;if(-1===n.id||!Fi(o.arc_length,n.arc_length)){n=o,e=t.int_points1[n.id];continue}let r=t.int_points1[o.id];r.edge_before===e.edge_before&&r.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(r.id=-1,o.id=-1,i=!0)}i&&(t.int_points1=t.int_points1.filter(t=>t.id>=0),t.int_points2=t.int_points2.filter(t=>t.id>=0),t.int_points1.forEach((t,e)=>t.id=e),t.int_points2.forEach((t,e)=>t.id=e))}function Er(t){for(let e of t)e.edge_before&&(e.edge_before.bvStart=void 0,e.edge_before.bvEnd=void 0,e.edge_before.bv=void 0,e.edge_before.overlap=void 0),e.edge_after&&(e.edge_after.bvStart=void 0,e.edge_after.bvEnd=void 0,e.edge_after.bv=void 0,e.edge_after.overlap=void 0);for(let e of t)e.edge_before&&(e.edge_before.bvEnd=2),e.edge_after&&(e.edge_after.bvStart=2)}function wr(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function Rr(t,e,n){let s,o,i=1;if(1===t.length)return 1;s=t[e];for(let r=e+1;r<t.length&&s.face===n&&(o=t[r],o.pt.equalTo(s.pt)&&o.edge_before===s.edge_before&&o.edge_after===s.edge_after);r++)i++;return i}function Or(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start&&e.shape.start.equalTo(n.pt)&&(n.is_vertex|=1),e.shape.end&&e.shape.end.equalTo(n.pt)&&(n.is_vertex|=2),1&n.is_vertex){n.edge_before=e.prev,e.prev&&(n.is_vertex=2);continue}if(2&n.is_vertex)continue;let s=t.addVertex(n.pt,e);n.edge_before=s}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof Mr&&1&n.is_vertex&&(n.edge_after=t.first)}}function Ar(t,e,n){const s=t.edge_before,o=e.edge_after,i=n.length;s.next=n[0],n[0].prev=s,n[i-1].next=o,o.prev=n[i-1]}ki.multiline=(...t)=>new ki.Multiline(...t);var{INSIDE:zr,OUTSIDE:Dr,BOUNDARY:Lr,OVERLAP_SAME:Fr,OVERLAP_OPPOSITE:Yr}=Oi,{NOT_VERTEX:Xr,START_VERTEX:kr,END_VERTEX:$r}=Oi;function Br(t,e){let n=e.clone().reverse(),[s,o]=Gr(t,n,3,!0);return s}function jr(t,e){let[n,s]=Gr(t,e,2,!0);return n}function Wr(t,e){let[n,s]=Gr(t,e,2,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];let i=[];for(let t of s.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return[o,i]}function Hr(t,e){let[n,s]=Gr(t,e,3,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];return o}function Ur(t,e){let n=t.clone(),s=e.clone(),o=Zr(n,s);return Ir(o),Or(n,o.int_points1_sorted),Or(s,o.int_points2_sorted),Tr(o),Ir(o),[o.int_points1_sorted.map(t=>t.pt),o.int_points2_sorted.map(t=>t.pt)]}function Vr(t,e,n,s){let o=qr(t,n.int_points1),i=qr(e,n.int_points2);for(Jr(o,e),Jr(i,t),Er(n.int_points1),Er(n.int_points2),wr(n.int_points1,e),wr(n.int_points2,t);Kr(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,s,o=t.int_points1.length;for(let i=0;i<o;i++){let r=t.int_points1_sorted[i];r.face!==e&&(n=i,e=r.face);let a,c=i,h=Rr(t.int_points1_sorted,i,e);a=c+h<o&&t.int_points1_sorted[c+h].face===e?c+h:n;let l=Rr(t.int_points1_sorted,a,e);s=null;for(let n=a;n<a+l;n++){let o=t.int_points1_sorted[n];if(o.face===e&&t.int_points2[o.id].face===t.int_points2[r.id].face){s=o;break}}if(null===s)continue;let d=r.edge_after,u=s.edge_before;if(2!==d.bv||2!==u.bv)continue;if(d!==u)continue;let p=t.int_points2[r.id],f=t.int_points2[s.id],m=p.edge_after,g=f.edge_before;2===m.bv&&2===g.bv&&m===g||(p=t.int_points2[s.id],f=t.int_points2[r.id],m=p.edge_after,g=f.edge_before),2===m.bv&&2===g.bv&&m===g&&d.setOverlap(m)}}(n),Qr(t,s,n.int_points1_sorted,!0),Qr(e,s,n.int_points2_sorted,!1),na(t,o,s,!0),na(e,i,s,!1)}function Gr(t,e,n,s){let o=t.clone(),i=e.clone(),r=Zr(o,i);return Ir(r),Or(o,r.int_points1_sorted),Or(i,r.int_points2_sorted),Tr(r),Ir(r),Vr(o,i,r,n),s&&function(t,e,n){!function(t,e,n,s){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===s.find(t=>t.face===n)&&t.addFace(n.first,n.last)}}(t,e,0,n.int_points2),function(t,e,n){if(0!==n.int_points1.length)for(let t=0;t<n.int_points1.length;t++){let e=n.int_points1[t],s=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===s.edge_before&&void 0!==s.edge_after&&(e.edge_before.next=s.edge_after,s.edge_after.prev=e.edge_before,e.edge_after=s.edge_after,s.edge_before=e.edge_before),void 0!==s.edge_before&&void 0===s.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(s.edge_before.next=e.edge_after,e.edge_after.prev=s.edge_before,s.edge_after=e.edge_after,e.edge_before=s.edge_before),void 0!==e.edge_before&&void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(e.pt)&&(e.edge_before.next=t.edge_after,t.edge_after.prev=e.edge_before,e.edge_after=t.edge_after,t.edge_before=e.edge_before);if(void 0!==s.edge_before&&void 0===s.edge_after)for(let t of n.int_points2_sorted)t!==s&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(s.pt)&&(s.edge_before.next=t.edge_after,t.edge_after.prev=s.edge_before,s.edge_after=t.edge_after,t.edge_before=s.edge_before)}}(0,0,n),ta(t,n.int_points1),ta(e,n.int_points2),ea(t,n.int_points1,n.int_points2),ea(t,n.int_points2,n.int_points1)}(o,i,r),[o,i]}function Zr(t,e){let n={int_points1:[],int_points2:[]};for(let s of t.edges){let t=e.edges.search(s.box);for(let e of t){let t=s.shape.intersect(e.shape);for(let o of t)Nr(s,o,n.int_points1),Nr(e,o,n.int_points2)}}return n}function qr(t,e){let n=[];for(let s of t.faces)e.find(t=>t.face===s)||n.push(s);return n}function Jr(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function Kr(t,e,n,s,o,i){let r,a,c,h=s.length,l=!1;for(let d=0;d<h;d++){let u=s[d];u.face!==r&&(a=d,r=u.face);let p,f=d,m=Rr(s,d,r);p=f+m<h&&s[f+m].face===r?f+m:a;let g=Rr(s,p,r);c=null;for(let t=p;t<p+g;t++){let e=s[t];if(e.face===r&&o[e.id].face===o[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,x=c.edge_before;if(y.bv!==Lr||x.bv==Lr)if(y.bv==Lr||x.bv!==Lr){if(y.bv===Lr&&x.bv===Lr&&y!=x||y.bv===zr&&x.bv===Dr||y.bv===Dr&&x.bv===zr){let t=y.next;for(;t!=x;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===Lr&&x.bv===Lr&&y!=x){let t,e=y.next;for(;e!=x;){if(e.bv!=Lr)if(void 0===t)t=e.bv;else if(e.bv!=t)throw $i.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,x.bv=t);continue}if(y.bv===zr&&x.bv===Dr||y.bv===Dr&&x.bv===zr){let s=y;for(;s!=x;){if(s.bvStart===y.bv&&s.bvEnd===x.bv){let[r,a]=s.shape.distanceTo(e);if(r<10*ki.DP_TOL){Nr(s,a.ps,n);let r=n[n.length-1];if(r.is_vertex&kr)r.edge_after=s,r.edge_before=s.prev,s.bvStart=Lr,s.bv=void 0,s.setInclusion(e);else if(r.is_vertex&$r)r.edge_after=s.next,s.bvEnd=Lr,s.bv=void 0,s.setInclusion(e);else{let t=e.addVertex(r.pt,s);r.edge_before=t,r.edge_after=t.next,t.setInclusion(e),t.next.bvStart=Lr,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);Nr(c,a.pe,o);let h=o[o.length-1];if(h.is_vertex&kr)h.edge_after=c,h.edge_before=c.prev;else if(h.is_vertex&$r)h.edge_after=c.next;else{let n=o.find(t=>t.edge_after===c),s=e.addVertex(h.pt,c);h.edge_before=s,h.edge_after=s.next,n&&(n.edge_after=s),s.bvStart=void 0,s.bvEnd=Lr,s.bv=void 0,s.setInclusion(t),s.next.bvStart=Lr,s.next.bvEnd=void 0,s.next.bv=void 0,s.next.setInclusion(t)}Ir(i),l=!0;break}}s=s.next}if(l)break;throw $i.UNRESOLVED_BOUNDARY_CONFLICT}}else x.bv=y.bv;else y.bv=x.bv}return l}function Qr(t,e,n,s){if(!n)return;let o,i,r,a;for(let c=0;c<n.length;c++){if(r=n[c],r.face!==o&&(i=c,o=r.face),o.isEmpty())continue;let h,l=c,d=Rr(n,c,o);h=l+d<n.length&&n[l+d].face===r.face?l+d:i,a=n[h];let u=h,p=Rr(n,u,o),f=r.edge_after,m=a.edge_before;if(f.bv===zr&&m.bv===zr&&1===e||f.bv===Dr&&m.bv===Dr&&2===e||(f.bv===Dr||m.bv===Dr)&&3===e&&!s||(f.bv===zr||m.bv===zr)&&3===e&&s||f.bv===Lr&&m.bv===Lr&&f.overlap&Fr&&s||f.bv===Lr&&m.bv===Lr&&f.overlap&Yr){t.removeChain(o,f,m);for(let t=l;t<l+d;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=d-1}}function ta(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before&&(n.edge_before.face=void 0),n.edge_after&&(n.edge_after.face=void 0)}function ea(t,e,n){for(let s of e){if(void 0===s.edge_before||void 0===s.edge_after)continue;if(s.face)continue;if(s.edge_after.face||s.edge_before.face)continue;let o=s.edge_after,i=s.edge_before;try{Bi.testInfiniteLoop(o)}catch(t){throw $i.CANNOT_COMPLETE_BOOLEAN_OPERATION}let r=t.addFace(o,i);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r)}}function na(t,e,n,s){for(let o of e){let e=o.first.bv;(1===n&&e===zr||3===n&&e===zr&&s||3===n&&e===Dr&&!s||2===n&&e===Dr)&&t.deleteFace(o)}}var sa=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:Ur,innerClip:Wr,intersect:jr,outerClip:Hr,removeNotRelevantChains:Qr,removeOldFaces:ta,restoreFaces:ea,subtract:Br,unify:function(t,e){let[n,s]=Gr(t,e,1,!0);return n}}),oa=RegExp("T.F..FFF.|T.F...F.."),ia=RegExp("T........|.T.......|...T.....|....T...."),ra=RegExp("FT.......|F..T.....|F...T...."),aa=RegExp("T.F..F..."),ca=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),ha=class{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&0===t.length?"F":"*").join("")}equal(){return oa.test(this.toString())}intersect(){return ia.test(this.toString())}touch(){return ra.test(this.toString())}inside(){return aa.test(this.toString())}covered(){return ca.test(this.toString())}};function la(t,e){let n,s=new ki.Ray(e),o=new ki.Line(s.pt,s.norm);const i=new ki.Box(s.box.xmin-ki.DP_TOL,s.box.ymin-ki.DP_TOL,s.box.xmax+ki.DP_TOL,s.box.ymax+ki.DP_TOL);if(t.box.not_intersect(i))return ki.OUTSIDE;let r=t.edges.search(i);if(0===r.length)return ki.OUTSIDE;for(let t of r)if(t.shape.contains(e))return ki.BOUNDARY;let a=[...t.faces],c=[];for(let t of r)for(let n of s.intersect(t.shape)){if(n.equalTo(e))return ki.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>Xi(t.pt.x,e.pt.x)?-1:Yi(t.pt.x,e.pt.x)?1:t.face_index<e.face_index?-1:t.face_index>e.face_index?1:t.edge.arc_length<e.edge.arc_length?-1:t.edge.arc_length>e.edge.arc_length?1:0);let h=0;for(let t=0;t<c.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;Li(n.length);)n=n.prev;let s=n.shape.tangentInEnd(),i=e.pt.translate(s),r=e.edge.shape.tangentInStart(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.pt.equalTo(e.edge.shape.end)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;Li(n.length);)n=n.next;let s=n.shape.tangentInStart(),i=e.pt.translate(s),r=e.edge.shape.tangentInEnd(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.edge.shape instanceof ki.Segment)h++;else{let t=e.edge.shape.box;Fi(e.pt.y,t.ymin)||Fi(e.pt.y,t.ymax)||h++}}return n=h%2==1?1:0,n}function da(t,e){return ma(t,e).intersect()}function ua(t,e){return ma(t,e).inside()}function pa(t,e){return ma(t,e).covered()}function fa(t,e){return pa(e,t)}function ma(t,e){return t instanceof ki.Line&&e instanceof ki.Line?function(t,e){let n=new ha,s=Ui(t,e);0===s.length?t.contains(e.pt)&&e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=s,n.I2E=t.split(s),n.E2I=e.split(s));return n}(t,e):t instanceof ki.Line&&e instanceof ki.Circle?function(t,e){let n=new ha,s=Vi(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Mr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new ki.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof ki.Line&&e instanceof ki.Box?function(t,e){let n=new ha,s=Gi(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Mr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();e.toSegments().some(t=>t.contains(s[0])&&t.contains(s[1]))?(n.I2I=[],n.I2B=[r[1]],n.I2E=[r[0],r[2]],n.E2I=[e]):(n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new ki.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof ki.Line&&e instanceof ki.Polygon?function(t,e){let n=new ha,s=lr(t,e),o=new Mr([t]),i=s.length>0?s.slice():t.sortPoints(s);return o.split(i),[...o].forEach(t=>t.setInclusion(e)),n.I2I=[...o].filter(t=>t.bv===ki.INSIDE).map(t=>t.shape),n.I2B=[...o].slice(1).map(t=>t.bv===ki.BOUNDARY?t.shape:t.shape.start),n.I2E=[...o].filter(t=>t.bv===ki.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof ki.Segment||t instanceof ki.Arc)&&e instanceof ki.Polygon?ga(t,e):(t instanceof ki.Segment||t instanceof ki.Arc)&&(e instanceof ki.Circle||e instanceof ki.Box)?ga(t,new ki.Polygon(e)):t instanceof ki.Polygon&&e instanceof ki.Polygon?ya(t,e):(t instanceof ki.Circle||t instanceof ki.Box)&&(e instanceof ki.Circle||e instanceof ki.Box)?ya(new ki.Polygon(t),new ki.Polygon(e)):(t instanceof ki.Circle||t instanceof ki.Box)&&e instanceof ki.Polygon?ya(new ki.Polygon(t),e):t instanceof ki.Polygon&&(e instanceof ki.Circle||e instanceof ki.Box)?ya(t,new ki.Polygon(e)):void 0}function ga(t,e){let n=new ha,s=function(t,e){return t instanceof ki.Line?lr(t,e):t instanceof ki.Segment?cr(t,e):t instanceof ki.Arc?hr(t,e):[]}(t,e),o=s.length>0?s.slice():t.sortPoints(s),i=new Mr([t]);i.split(o),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===ki.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===ki.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===ki.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let s of[t.start,t.end])switch(la(e,s)){case ki.INSIDE:n.B2I.push(s);break;case ki.BOUNDARY:n.B2B.push(s);break;case ki.OUTSIDE:n.B2E.push(s)}return n}function ya(t,e){let n=new ha,[s,o]=Ur(t,e),i=jr(t,e),r=Br(t,e),a=Br(e,t),[c,h]=Wr(t,e),l=Hr(t,e),d=Hr(e,t);return n.I2I=i.isEmpty()?[]:[i],n.I2B=h,n.I2E=r.isEmpty()?[]:[r],n.B2I=c,n.B2B=s,n.B2E=l,n.E2I=a.isEmpty()?[]:[a],n.E2B=d,n}var xa=Object.freeze({__proto__:null,contain:function(t,e){return ua(e,t)},cover:fa,covered:pa,disjoint:function(t,e){return!da(t,e)},equal:function(t,e){return ma(t,e).equal()},inside:ua,intersect:da,relate:ma,touch:function(t,e){return ma(t,e).touch()}}),va=class t{constructor(t=1,e=0,n=0,s=1,o=0,i=0){this.a=t,this.b=e,this.c=n,this.d=s,this.tx=o,this.ty=i}fromMatrix3x3(e){const[n,s,o]=e[0],[i,r,a]=e[1];return new t(n,i,s,r,o,a)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new t(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(e){return new t(this.a*e.a+this.c*e.b,this.b*e.a+this.d*e.b,this.a*e.c+this.c*e.d,this.b*e.c+this.d*e.d,this.a*e.tx+this.c*e.ty+this.tx,this.b*e.tx+this.d*e.ty+this.ty)}translate(...e){let n,s;if(1!=e.length||isNaN(e[0].x)||isNaN(e[0].y)){if(2!==e.length||"number"!=typeof e[0]||"number"!=typeof e[1])throw $i.ILLEGAL_PARAMETERS;n=e[0],s=e[1]}else n=e[0].x,s=e[0].y;return this.multiply(new t(1,0,0,1,n,s))}rotate(e,n=0,s=0){let o=Math.cos(e),i=Math.sin(e);return this.translate(n,s).multiply(new t(o,i,-i,o,0,0)).translate(-n,-s)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!ki.Utils.EQ(this.tx,t.tx)&&(!!ki.Utils.EQ(this.ty,t.ty)&&(!!ki.Utils.EQ(this.a,t.a)&&(!!ki.Utils.EQ(this.b,t.b)&&(!!ki.Utils.EQ(this.c,t.c)&&!!ki.Utils.EQ(this.d,t.d)))))}};ki.Matrix=va;ki.matrix=(...t)=>new ki.Matrix(...t);var ba=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const e=void 0===this.low?t.low:this.low<t.low?this.low:t.low,n=void 0===this.high?t.high:this.high>t.high?this.high:t.high,s=this.clone();return s.low=e,s.high=n,s}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},Pa=class t extends ba{clone(){return new t(this.low,this.high)}},Sa=class{constructor(t,e,n=null,s=null,o=null,i=0){if(this.left=n,this.right=s,this.parent=o,this.color=i,this.item={key:void 0,values:[]},void 0!==e&&this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)&&!Number.isNaN(n)){let t=e,s=n;t>s&&([t,s]=[s,t]),this.item.key=new Pa(t,s)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key&&0===this.item.values.length&&null===this.left&&null===this.right&&0===this.color}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const e=this.requireKey(),n=t.requireKey();return e.less_than(n)}_value_equal(t){const e=this.item.values[0],n=t.item.values[0];return e&&n&&e.equal_to?e.equal_to(n):e===n}equal_to(t){const e=this.requireKey(),n=t.requireKey();return e.equal_to(n)}intersect(t){const e=this.requireKey(),n=t.requireKey();return e.intersect(n)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const e=this.left.max?this.left.max.high:this.left.item.key.high,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(e,s.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const e=this.right.max?this.right.max.low:this.right.item.key.low,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(s.high,e)}},Ma=class t{constructor(){this.root=null,this.nil_node=new Sa}get size(){let t=0;return this.tree_walk(this.root,e=>t+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=>{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=>{const n=e.item.key.output();for(const s of e.item.values)t.push({key:n,value:s})}),t}isEmpty(){return null==this.root||this.root===this.nil_node}clear(){this.root=null}insert(t,e=t){if(void 0===t)return;const n=this.tree_search(this.root,new Sa(t));if(n)return n.item.values.push(e),n;const s=new Sa(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(s),this.recalc_max(s),s}exist(t,e=t){const n=this.tree_search(this.root,new Sa(t));return!!n&&(arguments.length<2||e===t||n.item.values.some(t=>t&&t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new Sa(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const s=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return s>=0?(n.item.values.splice(s,1),0===n.item.values.length&&this.tree_delete(n),n):void 0}search(t,e=(t,e)=>t===e?e.output():t){const n=new Sa(t),s=[];this.tree_search_interval(this.root,n,s);const o=[];for(const t of s)for(const n of t.item.values)o.push(e(n,t.item.key));return o}intersect_any(t){const e=new Sa(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>{for(const n of e.item.values)t(e.item.key,n)})}map(e){const n=new t;return this.tree_walk(this.root,t=>{for(const s of t.item.values)n.insert(t.item.key,e(s,t.item.key))}),n}*iterate(t,e=(t,e)=>t===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new Sa(t)):this.root&&(n=this.local_minimum(this.root));n;){for(const t of n.item.values)yield e(t,n.item.key);n=this.tree_successor(n)}}recalc_max(t){let e=t;for(;null!=e.parent;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(null==this.root||this.root===this.nil_node)this.root=t;else{for(;e!==this.nil_node;)n=e,e=t.less_than(e)?e.left:e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!==this.root&&1===e.parent.color;)e.parent===e.parent.parent.left?(n=e.parent.parent.right,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_left(e.parent.parent)));this.root.color=0}tree_delete(t){let e,n;e=t.left===this.nil_node||t.right===this.nil_node?t:this.tree_successor(t),n=e.left!==this.nil_node?e.left:e.right,n.parent=e.parent,e===this.root?this.root=n:(e===e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!==t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color&&this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root&&null!=n.parent&&0===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.right.color&&(e.color=1,e.left.color=0,this.rotate_right(e),e=n.parent.right),e.color=n.parent.color,n.parent.color=0,e.right.color=0,this.rotate_left(n.parent),n=this.root)):(e=n.parent.left,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.left.color&&(e.color=1,e.right.color=0,this.rotate_left(e),e=n.parent.left),e.color=n.parent.color,n.parent.color=0,e.left.color=0,this.rotate_right(n.parent),n=this.root));n.color=0}tree_search(t,e){if(null!=t&&t!==this.nil_node)return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_nearest_forward(t,e){let n=null,s=t;for(;s&&s!==this.nil_node;)s.less_than(e)?s.intersect(e)?(n=s,s=s.left):s=s.right:(n&&!s.less_than(n)||(n=s),s=s.left);return n||null}tree_search_interval(t,e,n){null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right===this.nil_node||t.not_intersect_right_subtree(e)||this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),n||t.right===this.nil_node||t.not_intersect_right_subtree(e)||(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;null!=e.left&&e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right&&e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,s;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,s=t.parent;null!=s&&s.right===n;)n=s,s=s.parent;e=s}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node&&(e.left.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node&&(e.right.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}tree_walk(t,e){null!=t&&t!==this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){1===e.color&&(0===e.left.color&&0===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,s=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,s=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==s)throw new Error("Red-black height property violated");return e+=n,e}},Na=class extends Set{constructor(t){super(t),this.index=new Ma,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:s}=t,o=n||t.box,i=s||t;return super.add(i),this.size>e&&this.index.insert(o,i),this}delete(t){const{key:e,value:n}=t,s=e||t.box,o=n||t;let i=super.delete(o);return i&&this.index.remove(s,o),i}clear(){super.clear(),this.index=new Ma}search(t){return this.index.search(t)}hit(t){let e=new ki.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=>t.on(e))}svg(){return[...this].reduce((t,e)=>t+e.svg(),"")}};ki.PlanarSet=Na;var Ia=class{get name(){throw $i.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw $i.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw $i.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new va).translate(...t))}rotate(t,e=new ki.Point){return this.transform((new va).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new va).scale(t,e))}transform(...t){throw $i.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw $i.CANNOT_INVOKE_ABSTRACT_METHOD}};ki.Point=class t extends Ia{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"point"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw $i.ILLEGAL_PARAMETERS}}get box(){return new ki.Box(this.x,this.y,this.x,this.y)}clone(){return new ki.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return ki.Utils.EQ(this.x,t.x)&&ki.Utils.EQ(this.y,t.y)}lessThan(t){return!!ki.Utils.LT(this.y,t.y)||!(!ki.Utils.EQ(this.y,t.y)||!ki.Utils.LT(this.x,t.x))}transform(t){return new ki.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new ki.Vector(this,t.pt);if(ki.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),s=t.norm.multiply(n);return this.translate(s)}leftTo(t){let e=new ki.Vector(t.pt,this);return ki.Utils.GT(e.dot(t.norm),0)}distanceTo(e){if(e instanceof t){let t=e.x-this.x,n=e.y-this.y;return[Math.sqrt(t*t+n*n),new ki.Segment(this,e)]}return e instanceof ki.Line?ki.Distance.point2line(this,e):e instanceof ki.Circle?ki.Distance.point2circle(this,e):e instanceof ki.Segment?ki.Distance.point2segment(this,e):e instanceof ki.Arc?ki.Distance.point2arc(this,e):e instanceof ki.Polygon?ki.Distance.point2polygon(this,e):e instanceof ki.PlanarSet?ki.Distance.shape2planarSet(this,e):e instanceof ki.Multiline?ki.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof ki.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw ki.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const e=t.r??3;return`\n<circle cx="${this.x}" cy="${this.y}" r="${e}"\n ${Hi({fill:"red",...t})} />`}};var _a=(...t)=>new ki.Point(...t);ki.point=_a;ki.Vector=class extends Ia{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"vector"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{start:e,end:n}=t[0];return this.x=n.x-e.x,void(this.y=n.y-e.y)}if(2===t.length){let e=t[0],n=t[1];if("number"==typeof e&&"number"==typeof n)return this.x=e,void(this.y=n);if(e instanceof ki.Point&&n instanceof ki.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw $i.ILLEGAL_PARAMETERS}}clone(){return new ki.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return ki.Utils.EQ_0(this.length)}equalTo(t){return ki.Utils.EQ(this.x,t.x)&&ki.Utils.EQ(this.y,t.y)}multiply(t){return new ki.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(this.isZeroLength())throw $i.ZERO_DIVISION;return new ki.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new ki.Point){if(0===e.x&&0===e.y)return this.transform((new va).rotate(t));throw $i.OPERATION_IS_NOT_SUPPORTED}transform(t){return new ki.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new ki.Vector(-this.y,this.x)}rotate90CW(){return new ki.Vector(this.y,-this.x)}invert(){return new ki.Vector(-this.x,-this.y)}add(t){return new ki.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new ki.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),s=Math.atan2(e.cross(n),e.dot(n));return s<0&&(s+=2*Math.PI),s}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var Ca=(...t)=>new ki.Vector(...t);ki.vector=Ca;ki.Segment=class t extends Ia{constructor(...t){if(super(),this.ps=new ki.Point,this.pe=new ki.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new ki.Point(e[0],e[1]),void(this.pe=new ki.Point(e[2],e[3]))}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new ki.Point(e.x,e.y),void(this.pe=new ki.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof ki.Point)){if(2===t.length&&t[0]instanceof ki.Point&&t[1]instanceof ki.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new ki.Point(t[0],t[1]),void(this.pe=new ki.Point(t[2],t[3]));throw $i.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new ki.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new ki.Vector(this.start,this.end).slope}get box(){return new ki.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return ki.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Line?qi(this,t):t instanceof ki.Ray?gr(t,this):t instanceof ki.Segment?Ji(this,t):t instanceof ki.Circle?Qi(this,t):t instanceof ki.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=Ji(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ki.Arc?tr(this,t):t instanceof ki.Polygon?cr(this,t):t instanceof ki.Multiline?Sr(this,t):void 0}distanceTo(t){if(t instanceof ki.Point){let[e,n]=ki.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Circle){let[e,n]=ki.Distance.segment2circle(this,t);return[e,n]}if(t instanceof ki.Line){let[e,n]=ki.Distance.segment2line(this,t);return[e,n]}if(t instanceof ki.Segment){let[e,n]=ki.Distance.segment2segment(this,t);return[e,n]}if(t instanceof ki.Arc){let[e,n]=ki.Distance.segment2arc(this,t);return[e,n]}if(t instanceof ki.Polygon){let[e,n]=ki.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ki.PlanarSet){let[e,n]=ki.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ki.Multiline)return ki.Distance.shape2multiline(this,t)}tangentInStart(){return new ki.Vector(this.start,this.end).normalize()}tangentInEnd(){return new ki.Vector(this.end,this.start).normalize()}reverse(){return new t(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new ki.Segment(this.start,t),new ki.Segment(t,this.end)]}middle(){return new ki.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new ki.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=ki.Distance.point2segment(t,this);return e}definiteIntegral(t=0){return(this.end.x-this.start.x)*(this.start.y-t+(this.end.y-t))/2}transform(e=new ki.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new ki.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return`\n<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${Hi(t)} />`}};var Ta=(...t)=>new ki.Segment(...t);ki.segment=Ta;var{vector:Ea}=ki;ki.Line=class t extends Ia{constructor(...e){if(super(),this.pt=new ki.Point,this.norm=new ki.Vector(0,1),0!==e.length){if(1===e.length&&e[0]instanceof Object&&"line"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new ki.Point(t),void(this.norm=new ki.Vector(n))}if(2===e.length){let n=e[0],s=e[1];if(n instanceof ki.Point&&s instanceof ki.Point)return this.pt=n,this.norm=t.points2norm(n,s),void(this.norm.dot(Ea(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof ki.Point&&s instanceof ki.Vector){if(ki.Utils.EQ_0(s.x)&&ki.Utils.EQ_0(s.y))throw $i.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=s.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ea(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof ki.Vector&&s instanceof ki.Point){if(ki.Utils.EQ_0(n.x)&&ki.Utils.EQ_0(n.y))throw $i.ILLEGAL_PARAMETERS;return this.pt=s.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ea(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw $i.ILLEGAL_PARAMETERS}}clone(){return new ki.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new ki.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new ki.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(Ea(this.pt.x,this.pt.y))]}parallelTo(t){return ki.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new ki.Vector(this.pt,t);return ki.Utils.EQ_0(this.norm.dot(e))}coord(t){return Ea(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Line?Ui(this,t):t instanceof ki.Ray?vr(t,this):t instanceof ki.Circle?Vi(this,t):t instanceof ki.Box?Gi(this,t):t instanceof ki.Segment?qi(t,this):t instanceof ki.Arc?Zi(this,t):t instanceof ki.Polygon?lr(this,t):t instanceof ki.Multiline?Sr(this,t):void 0}distanceTo(t){if(t instanceof ki.Point){let[e,n]=ki.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Circle){let[e,n]=ki.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Segment){let[e,n]=ki.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof ki.Arc){let[e,n]=ki.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof ki.Polygon){let[e,n]=ki.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof ki.Point)return[new ki.Ray(t,this.norm),new ki.Ray(t,this.norm)];{let e=new ki.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new ki.Point){return new ki.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ki.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=>this.coord(t)<this.coord(e)?-1:this.coord(t)>this.coord(e)?1:0)}get name(){return"line"}svg(t,e={}){let n=Gi(this,t);if(0===n.length)return"";let s=n[0],o=2===n.length?n[1]:n.find(t=>!t.equalTo(s));return void 0===o&&(o=s),new ki.Segment(s,o).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw $i.ILLEGAL_PARAMETERS;return new ki.Vector(t,e).normalize().rotate90CCW()}};var wa=(...t)=>new ki.Line(...t);ki.line=wa;ki.Circle=class extends Ia{constructor(...t){if(super(),this.pc=new ki.Point,this.r=1,1===t.length&&t[0]instanceof Object&&"circle"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new ki.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof ki.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new ki.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new ki.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){return t instanceof ki.Point?ki.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof ki.Segment?ki.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&ki.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ki.Arc?0===this.intersect(t).length&&ki.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&ki.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof ki.Circle?0===this.intersect(t).length&&ki.Utils.LE(t.r,this.r)&&ki.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new ki.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw $i.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw $i.OPERATION_IS_NOT_SUPPORTED;return new ki.Circle(this.pc,this.r*t)}transform(t=new ki.Matrix){return new ki.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Line?Vi(t,this):t instanceof ki.Ray?xr(t,this):t instanceof ki.Segment?Qi(t,this):t instanceof ki.Circle?er(t,this):t instanceof ki.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=Qi(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ki.Arc?sr(t,this):t instanceof ki.Polygon?dr(this,t):t instanceof ki.Multiline?Sr(this,t):void 0}distanceTo(t){if(t instanceof ki.Point){let[e,n]=ki.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Circle){let[e,n]=ki.Distance.circle2circle(this,t);return[e,n]}if(t instanceof ki.Line){let[e,n]=ki.Distance.circle2line(this,t);return[e,n]}if(t instanceof ki.Segment){let[e,n]=ki.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Arc){let[e,n]=ki.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Polygon){let[e,n]=ki.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ki.PlanarSet){let[e,n]=ki.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ki.Multiline){let[e,n]=ki.Distance.shape2multiline(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return`\n<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"\n ${Hi({fill:"none",...t})} />`}};ki.circle=(...t)=>new ki.Circle(...t);ki.Arc=class extends Ia{constructor(...t){if(super(),this.pc=new ki.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length&&t[0]instanceof Object&&"arc"===t[0].name){let{pc:e,r:n,startAngle:s,endAngle:o,counterClockwise:i}=t[0];this.pc=new ki.Point(e.x,e.y),this.r=n,this.startAngle=s,this.endAngle=o,this.counterClockwise=i}else{let[e,n,s,o,i]=[...t];e&&e instanceof ki.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==s&&(this.startAngle=s),void 0!==o&&(this.endAngle=o),void 0!==i&&(this.counterClockwise=i)}}clone(){return new ki.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(ki.Utils.EQ(Math.abs(t-e),ki.PIx2))return ki.PIx2;Math.abs(t)>ki.PIx2&&(t-=Math.trunc(t/ki.PIx2)*ki.PIx2),t<0&&(t+=ki.PIx2),Math.abs(e)>ki.PIx2&&(e-=Math.trunc(e/ki.PIx2)*ki.PIx2),e<0&&(e+=ki.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=ki.PIx2),n}get start(){return new ki.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new ki.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let t=this.breakToFunctional().reduce((t,e)=>t.merge(e.start.box),new ki.Box);return t=t.merge(this.end.box),t}contains(t){if(!ki.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new ki.Vector(this.pc,t).slope,n=new ki.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return ki.Utils.LE(n.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let e=new ki.Vector(this.pc,t).slope;return[new ki.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new ki.Arc(this.pc,this.r,e,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new ki.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(0===t)return this.start;if(t===this.length)return this.end;let e=t/this.length,n=this.counterClockwise?this.startAngle+this.sweep*e:this.startAngle-this.sweep*e;return new ki.Arc(this.pc,this.r,this.startAngle,n,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Line?Zi(t,this):t instanceof ki.Ray?yr(t,this):t instanceof ki.Circle?sr(this,t):t instanceof ki.Segment?tr(t,this):t instanceof ki.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=tr(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof ki.Arc?nr(this,t):t instanceof ki.Polygon?hr(this,t):t instanceof ki.Multiline?Sr(this,t):void 0}distanceTo(t){if(t instanceof ki.Point){let[e,n]=ki.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Circle){let[e,n]=ki.Distance.arc2circle(this,t);return[e,n]}if(t instanceof ki.Line){let[e,n]=ki.Distance.arc2line(this,t);return[e,n]}if(t instanceof ki.Segment){let[e,n]=ki.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Arc){let[e,n]=ki.Distance.arc2arc(this,t);return[e,n]}if(t instanceof ki.Polygon){let[e,n]=ki.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof ki.PlanarSet){let[e,n]=ki.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof ki.Multiline)return ki.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,s=this.endAngle;ki.Utils.EQ(Math.abs(n-s),ki.PIx2)&&(s=n),Math.abs(n)>ki.PIx2&&(n-=Math.trunc(n/ki.PIx2)*ki.PIx2),n<0&&(n+=ki.PIx2),Math.abs(s)>ki.PIx2&&(s-=Math.trunc(s/ki.PIx2)*ki.PIx2),s<0&&(s+=ki.PIx2);let o,i,r,a=n;this.counterClockwise?(i=Math.ceil(n/(Math.PI/2))%4,r=1):(i=Math.floor(n/(Math.PI/2))%4,r=-1);for(let s=0,c=i;s<4;s++,c=(c+r+4)%4){if(o=e[c],o===a)continue;let s=this.counterClockwise?o-n:n-o;if(s<0&&(s+=ki.PIx2),s>this.sweep)break;t.push(new ki.Arc(this.pc,this.r,a,o,this.counterClockwise)),a=o}return 0===t.length?(t.push(this),t):(o=s,a!==o&&t.push(new ki.Arc(this.pc,this.r,a,o,this.counterClockwise)),t)}tangentInStart(){let t=new ki.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new ki.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new ki.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new ki.Matrix){let e=this.start.transform(t),n=this.end.transform(t),s=this.pc.transform(t),o=this.counterClockwise;return t.a*t.d<0&&(o=!o),ki.Arc.arcSE(s,e,n,o)}static arcSE(t,e,n,s){let{vector:o}=ki,i=o(t,e).slope,r=o(t,n).slope;ki.Utils.EQ(i,r)&&(r+=2*Math.PI,s=!0);let a=o(t,e).length;return new ki.Arc(t,a,i,r,s)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new ki.Segment(this.start,this.end).definiteIntegral(t),n=ki.Utils.EQ(this.sweep,ki.PIx2)?0:this.circularSegmentArea();return this.counterClockwise?e-n:e+n}circularSegmentArea(){return.5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:e}=ki;return t.slice().sort((t,n)=>{let s=e(this.pc,t).slope,o=e(this.pc,n).slope;return s<o?-1:s>o?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if(ki.Utils.EQ(this.sweep,2*Math.PI)){return new ki.Circle(this.pc,this.r).svg(t)}return`\n<path d="M${this.start.x},${this.start.y}\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}"\n ${Hi({fill:"none",...t})} />`}};ki.arc=(...t)=>new ki.Arc(...t);ki.Box=class t extends Ia{constructor(t=void 0,e=void 0,n=void 0,s=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new ki.Point(this.xmin,this.ymin)}get high(){return new ki.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new ki.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmax<t.xmin||this.xmin>t.xmax||this.ymax<t.ymin||this.ymin>t.ymax}intersect(t){return!this.not_intersect(t)}merge(e){return new t(void 0===this.xmin?e.xmin:Math.min(this.xmin,e.xmin),void 0===this.ymin?e.ymin:Math.min(this.ymin,e.ymin),void 0===this.xmax?e.xmax:Math.max(this.xmax,e.xmax),void 0===this.ymax?e.ymax:Math.max(this.ymax,e.ymax))}less_than(t){return!!this.low.lessThan(t.low)||!(!this.low.equalTo(t.low)||!this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,s){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new ki.Point(this.xmin,this.ymin),new ki.Point(this.xmax,this.ymin),new ki.Point(this.xmax,this.ymax),new ki.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new ki.Segment(t[0],t[1]),new ki.Segment(t[1],t[2]),new ki.Segment(t[2],t[3]),new ki.Segment(t[3],t[0])]}rotate(t,e=new ki.Point){throw $i.OPERATION_IS_NOT_SUPPORTED}transform(e=new ki.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof ki.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof ki.Segment?t.vertices.every(t=>this.contains(t)):t instanceof ki.Box?t.toSegments().every(t=>this.contains(t)):t instanceof ki.Circle?this.contains(t.box):t instanceof ki.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===tr(e,t).length):!(t instanceof ki.Line||t instanceof ki.Ray)&&(t instanceof ki.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof ki.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=>e.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=>{t[0]<n[0]&&(n=t)}),n}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\n<rect x="${this.xmin}" y="${this.ymin}" width="${e}" height="${n}"\n ${Hi({fill:"none",...t})} />`}};ki.box=(...t)=>new ki.Box(...t);ki.Edge=class{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof ki.Segment}get isArc(){return this.shape instanceof ki.Arc}get isLine(){return this.shape instanceof ki.Line}get isRay(){return this.shape instanceof ki.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(void 0!==this.bv)return this.bv;if(this.shape instanceof ki.Line||this.shape instanceof ki.Ray)return this.bv=ki.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=la(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=la(t,this.end)),this.bvStart===ki.OUTSIDE||this.bvEnd==ki.OUTSIDE)this.bv=ki.OUTSIDE;else if(this.bvStart===ki.INSIDE||this.bvEnd==ki.INSIDE)this.bv=ki.INSIDE;else{let e=la(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,s=t.shape;n instanceof ki.Segment&&s instanceof ki.Segment?n.start.equalTo(s.start)&&n.end.equalTo(s.end)?e=ki.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&(e=ki.OVERLAP_OPPOSITE):(n instanceof ki.Arc&&s instanceof ki.Arc||n instanceof ki.Segment&&s instanceof ki.Arc||n instanceof ki.Arc&&s instanceof ki.Segment)&&(n.start.equalTo(s.start)&&n.end.equalTo(s.end)&&n.middle().equalTo(s.middle())?e=ki.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&n.middle().equalTo(s.middle())&&(e=ki.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof ki.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof ki.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if(ki.Utils.EQ(e.sweep,2*Math.PI)){let s=e.counterClockwise?1:-1,o=new ki.Arc(e.pc,e.r,e.startAngle,e.startAngle+s*Math.PI,e.counterClockwise),i=new ki.Arc(e.pc,e.r,e.startAngle+s*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${o.r},${o.r} 0 ${t},${n} ${o.end.x},${o.end.y}\n A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}`}return t=e.sweep<=Math.PI?"0":"1",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var Ra=class extends Bi{constructor(t,e){super(t,e),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let e=t||this.first,n=!this.first||!!t&&t===this.first;return t=e?e.next:void 0,{value:e,done:n}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,e){return super.insert(t,e),this.setCircularLinks(),this}remove(t){return super.remove(t),this}};ki.Face=class t extends Ra{constructor(e,...n){if(super(),this._box=void 0,this._orientation=void 0,0!==n.length){if(1===n.length)if(n[0]instanceof Array){let s=n[0];if(0===s.length)return;if(s.every(t=>t instanceof ki.Point)){let n=t.points2segments(s);this.shapes2face(e.edges,n)}else if(s.every(t=>t instanceof Array&&2===t.length)){let n=s.map(t=>new ki.Point(t[0],t[1])),o=t.points2segments(n);this.shapes2face(e.edges,o)}else if(s.every(t=>t instanceof ki.Segment||t instanceof ki.Arc))this.shapes2face(e.edges,s);else if(s.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of s){let n;n="segment"===e.name?new ki.Segment(e):new ki.Arc(e),t.push(n)}this.shapes2face(e.edges,t)}}else if(n[0]instanceof t){let t=n[0];this.first=t.first,this.last=t.last;for(let n of t)e.edges.add(n)}else if(n[0]instanceof ki.Circle)this.shapes2face(e.edges,[n[0].toArc(Ei)]);else if(n[0]instanceof ki.Box){let t=n[0];this.shapes2face(e.edges,[new ki.Segment(new ki.Point(t.xmin,t.ymin),new ki.Point(t.xmax,t.ymin)),new ki.Segment(new ki.Point(t.xmax,t.ymin),new ki.Point(t.xmax,t.ymax)),new ki.Segment(new ki.Point(t.xmax,t.ymax),new ki.Point(t.xmin,t.ymax)),new ki.Segment(new ki.Point(t.xmin,t.ymax),new ki.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof ki.Edge&&n[1]instanceof ki.Edge&&(this.first=n[0],this.last=n[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(void 0===this._box){let t=new ki.Box;for(let e of this)t=t.merge(e.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n<t.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new ki.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new ki.Edge(n);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,e){return super.insert(t,e),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],e=this.last;do{e.shape=e.shape.reverse(),t.push(e),e=e.prev}while(e!==this.last);this.first=void 0,this.last=void 0;for(let e of t)void 0===this.first?(e.prev=e,e.next=e,this.first=e,this.last=e):(e.prev=this.last,this.last.next=e,this.last=e,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(e);void 0!==this._orientation&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,e=this.box.ymin;for(let n of this)t+=n.shape.definiteIntegral(e);return t}orientation(){if(void 0===this._orientation){let t=this.signedArea();ki.Utils.EQ_0(t)?this._orientation=wi.NOT_ORIENTABLE:ki.Utils.LT(t,0)?this._orientation=wi.CCW:this._orientation=wi.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let s=[];for(let o of t){let i=e.search(o.box);for(let e of i){if(o===e)continue;if(e.face!==t)continue;if(o.shape instanceof ki.Segment&&e.shape instanceof ki.Segment&&(o.next===e||o.prev===e))continue;let i=o.shape.intersect(e.shape);for(let t of i)if((!t.equalTo(o.start)||!t.equalTo(e.end)||e!==o.prev)&&(!t.equalTo(o.end)||!t.equalTo(e.start)||e!==o.next)&&(s.push(t),n))break;if(s.length>0&&n)break}if(s.length>0&&n)break}return s}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)&&(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new ki.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}};ki.Ray=class t extends Ia{constructor(...t){if(super(),this.pt=new ki.Point,this.norm=new ki.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof ki.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof ki.Vector))throw $i.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new ki.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new ki.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||0===t?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new ki.Vector(this.pt,t);return ki.Utils.EQ_0(this.norm.dot(e))&&ki.Utils.GE(e.cross(this.norm),0)}coord(t){return Ca(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new ki.Segment(this.pt,t),new ki.Ray(t,this.norm)]:[]}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Segment?gr(this,t):t instanceof ki.Arc?yr(this,t):t instanceof ki.Line?vr(this,t):t instanceof ki.Ray?(n=t,Ui(mr(e=this),mr(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof ki.Circle?xr(this,t):t instanceof ki.Box?function(t,e){return Gi(mr(t),e).filter(e=>t.contains(e))}(this,t):t instanceof ki.Polygon?br(this,t):t instanceof ki.Multiline?Sr(this,t):void 0;var e,n}rotate(t,e=new ki.Point){return new ki.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new ki.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=Gi(new ki.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new ki.Segment(this.pt,n[0]).svg(e)}};ki.ray=(...t)=>new ki.Ray(...t);var Oa=class t{constructor(){this.faces=new ki.PlanarSet,this.edges=new ki.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof ki.Circle||t[0]instanceof ki.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(t=>t instanceof Array))if(e.every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))this.faces.add(new ki.Face(this,e));else for(let t of e)if(t instanceof Array&&t[0]instanceof Array&&t[0].every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))for(let e of t)this.faces.add(new ki.Face(this,e));else this.faces.add(new ki.Face(this,t));else this.faces.add(new ki.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new ki.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let e=new t;for(let t of this.faces)e.addFace(t.shapes);return e}createFromArray(e){const n=new t;return e.forEach(t=>[...t.faces].forEach(t=>n.addFace(t.shapes))),n}isEmpty(){return 0===this.edges.size||0===this.faces.size}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((t,e)=>t+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new ki.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let t of this.edges)t.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(null===n.face){t=n,e=!0;break}if(e){let e=t;do{e=e.next}while(e.next!==t);this.addFace(t,e)}}}removeChain(t,e,n){if(n.next!==e){for(let s=e;s!==n.next;s=s.next)if(t.remove(s),this.edges.delete(s),t.isEmpty()){this.deleteFace(t);break}}else this.deleteFace(t)}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new ki.Edge(n[0]),o=e.prev;return e.face.insert(s,o),this.edges.delete(e),this.edges.add(s),e.shape=n[1],this.edges.add(e),s}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(t=>t.isValid()&&!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let s,o,i={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=ur(t,n);for(let s of e)Nr(t,s,i.int_points1),Nr(n,s,i.int_points2)}if(0===i.int_points1.length)return e;i.int_points1_sorted=_r(i.int_points1),i.int_points2_sorted=_r(i.int_points2),Or(n,i.int_points1_sorted),Or(e,i.int_points2_sorted),Tr(i),i.int_points1_sorted=_r(i.int_points1),i.int_points2_sorted=_r(i.int_points2),Er(i.int_points1),wr(i.int_points1,e);for(let t of i.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(i.int_points2[t.id]=-1,t.id=-1);if(i.int_points1=i.int_points1.filter(t=>t.id>=0),i.int_points2=i.int_points2.filter(t=>t.id>=0),i.int_points1.forEach((t,e)=>{t.id=e}),i.int_points2.forEach((t,e)=>{t.id=e}),0===i.int_points1.length)return e;i.int_points1_sorted=_r(i.int_points1),i.int_points2_sorted=_r(i.int_points2);for(let t=1;t<i.int_points1_sorted.length;t++)if(o=i.int_points1_sorted[t],s=i.int_points1_sorted[t-1],o.edge_before&&1===o.edge_before.bv){let t=s.edge_after,r=o.edge_before,a=n.getChain(t,r);Ar(i.int_points2[s.id],i.int_points2[o.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new ki.Edge(t.shape.reverse()));for(let t=0;t<a.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];Ar(i.int_points2[o.id],i.int_points2[s.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new Mr([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),void 0!==e)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((t,e)=>e.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=>[...t.faces][0].orientation()===e);for(let s of t){let t=[...s.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=>e.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size<=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=>{t.faces.forEach(t=>n.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?wi.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=>{this.isOuter(e)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof ki.Point){let e=la(this,t);return 1===e||2===e}return fa(this,t)}distanceTo(t){if(t instanceof ki.Point){let[e,n]=ki.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Circle||t instanceof ki.Line||t instanceof ki.Segment||t instanceof ki.Arc){let[e,n]=ki.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof ki.Polygon){let e,n,s=[Number.POSITIVE_INFINITY,new ki.Segment];for(let o of this.edges){let i=s[0];[e,n]=ki.Distance.shape2planarSet(o.shape,t.edges,i),ki.Utils.LT(e,i)&&(s=[e,n])}return s}}intersect(t){return t instanceof ki.Point?this.contains(t)?[t]:[]:t instanceof ki.Line?lr(t,this):t instanceof ki.Ray?br(t,this):t instanceof ki.Circle?dr(t,this):t instanceof ki.Segment?cr(t,this):t instanceof ki.Arc?hr(t,this):t instanceof ki.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let s of t.edges)n=[...n,...pr(s,e)];return n}(t,this):t instanceof ki.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let s of t)n=[...n,...pr(s,e)];return n}(t,this):void 0}translate(e){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.translate(e)));return n}rotate(e=0,n=new ki.Point){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.rotate(e,n)));return s}scale(e,n){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.scale(e,n)));return s}transform(e=new ki.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.transform(e)));return n}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=>t+e.svg(),"")}svg(t={}){let e=`\n<path ${Hi({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};ki.Polygon=Oa;ki.polygon=(...t)=>new ki.Polygon(...t);var{Circle:Aa,Line:za,Point:Da,Vector:La,Utils:Fa}=ki;ki.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new La(t.pc,e),s=t.r*t.r,o=n.dot(n);return Fa.EQ_0(o)?new Da(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(s/o))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(Fa.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),s=new La(t.pc,e.pc);s=s.normalize();let o=t.pc.translate(s.multiply(n));return new za(o,s)}{let n=new La(t.pc,e.pc),s=t.r*t.r/(n.dot(n)-e.r*e.r),o=t.pc.translate(n.multiply(s)),i=Math.abs(s)*e.r;return new Aa(o,i)}}static inverseLine(t,e){const[n,s]=t.pc.distanceTo(e);if(Fa.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),o=new La(t.pc,s.end);return o=o.multiply(e/n),new Aa(t.pc.translate(o),e)}}inverse(e){return e instanceof Da?t.inversePoint(this.circle,e):e instanceof Aa?t.inverseCircle(this.circle,e):e instanceof za?t.inverseLine(this.circle,e):void 0}};ki.inversion=t=>new ki.Inversion(t);ki.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new ki.Vector(t,n).length,new ki.Segment(t,n)]}static point2circle(t,e){let[n,s]=t.distanceTo(e.center);if(ki.Utils.EQ_0(n))return[e.r,new ki.Segment(t,e.toArc().start)];{let s=Math.abs(n-e.r),o=new ki.Vector(e.pc,t).normalize().multiply(e.r),i=e.pc.translate(o);return[s,new ki.Segment(t,i)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let s,o,i=new ki.Vector(n.start,n.end),r=new ki.Vector(n.start,e),a=new ki.Vector(n.end,e),c=i.dot(r),h=-i.dot(a);if(ki.Utils.GE(c,0)&&ki.Utils.GE(h,0)){let t=n.tangentInStart();return s=Math.abs(t.cross(r)),o=n.start.translate(t.multiply(t.dot(r))),[s,new ki.Segment(e,o)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let s,o,i=new ki.Circle(n.pc,n.r),r=[];return[s,o]=t.point2circle(e,i),o.end.on(n)&&r.push(t.point2circle(e,i)),r.push(t.point2point(e,n.start)),r.push(t.point2point(e,n.end)),t.sort(r),r[0]}static point2edge(e,n){return n.shape instanceof ki.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}static segment2segment(e,n){let s=Ji(e,n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o,i,r=[];return[o,i]=t.point2segment(n.start,e),r.push([o,i.reverse()]),[o,i]=t.point2segment(n.end,e),r.push([o,i.reverse()]),r.push(t.point2segment(e.start,n)),r.push(t.point2segment(e.end,n)),t.sort(r),r[0]}static segment2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=new ki.Line(e.ps,e.pe),[i,r]=t.point2line(n.center,o);if(ki.Utils.GE(i,n.r)&&r.end.on(e))return t.point2circle(r.end,n);{let[s,o]=t.point2circle(e.start,n),[i,r]=t.point2circle(e.end,n);return ki.Utils.LT(s,i)?[s,o]:[i,r]}}static segment2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=new ki.Line(e.ps,e.pe),i=new ki.Circle(n.pc,n.r),[r,a]=t.point2line(i.center,o);if(ki.Utils.GE(r,i.r)&&a.end.on(e)){let[e,s]=t.point2circle(a.end,i);if(s.end.on(n))return[e,s]}let c,h,l=[];return l.push(t.point2arc(e.start,n)),l.push(t.point2arc(e.end,n)),[c,h]=t.point2segment(n.start,e),l.push([c,h.reverse()]),[c,h]=t.point2segment(n.end,e),l.push([c,h.reverse()]),t.sort(l),l[0]}static circle2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];if(e.center.equalTo(n.center)){let s=e.toArc(),o=n.toArc();return t.point2point(s.start,o.start)}{let s=new ki.Line(e.center,n.center),o=s.intersect(e),i=s.intersect(n),r=[];return r.push(t.point2point(o[0],i[0])),r.push(t.point2point(o[0],i[1])),r.push(t.point2point(o[1],i[0])),r.push(t.point2point(o[1],i[1])),t.sort(r),r[0]}}static circle2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let[o,i]=t.point2line(e.center,n),[r,a]=t.point2circle(i.end,e);return a=a.reverse(),[r,a]}static arc2line(e,n){let s=n.intersect(e);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=new ki.Circle(e.center,e.r),[i,r]=t.point2line(o.center,n);if(!ki.Utils.GE(i,o.r)){let s=[];return s.push(t.point2line(e.start,n)),s.push(t.point2line(e.end,n)),t.sort(s),s[0]}{let[n,s]=t.point2circle(r.end,o);if(s.end.on(e))return[n,s]}}static arc2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=new ki.Circle(e.center,e.r),[i,r]=t.circle2circle(o,n);if(r.start.on(e))return[i,r];{let s=[];return s.push(t.point2circle(e.start,n)),s.push(t.point2circle(e.end,n)),t.sort(s),s[0]}}static arc2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new ki.Segment(s[0],s[0])];let o=new ki.Circle(e.center,e.r),i=new ki.Circle(n.center,n.r),[r,a]=t.circle2circle(o,i);if(a.start.on(e)&&a.end.on(n))return[r,a];{let s,o,i=[];return[s,o]=t.point2arc(e.start,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(e.end,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(n.start,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2arc(n.end,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2point(e.start,n.start),i.push([s,o]),[s,o]=t.point2point(e.start,n.end),i.push([s,o]),[s,o]=t.point2point(e.end,n.start),i.push([s,o]),[s,o]=t.point2point(e.end,n.end),i.push([s,o]),t.sort(i),i[0]}}static point2polygon(e,n){let s=[Number.POSITIVE_INFINITY,new ki.Segment];for(let o of n.edges){let[n,i]=t.point2edge(e,o);ki.Utils.LT(n,s[0])&&(s=[n,i])}return s}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ki.Segment];for(let s of e.edges){let[e,o]=t.distanceTo(s.shape);ki.Utils.LT(e,n[0])&&(n=[e,o])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new ki.Segment];for(let s of t.edges)for(let t of e.edges){let[e,o]=s.shape.distanceTo(t.shape);ki.Utils.LT(e,n[0])&&(n=[e,o])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),s=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),o=n*n+s*s,i=t.merge(e),r=i.xmax-i.xmin,a=i.ymax-i.ymin;return[o,r*r+a*a]}static minmax_tree_process_level(e,n,s,o){let i,r;for(let a of n){[i,r]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof ki.Edge?o.insert([i,r],t.shape):o.insert([i,r],t);ki.Utils.LT(r,s)&&(s=r)}if(0===n.length)return s;let a=[...n.map(t=>t.left.isNil()?void 0:t.left).filter(t=>void 0!==t),...n.map(t=>t.right.isNil()?void 0:t.right).filter(t=>void 0!==t)].filter(n=>{let[o,i]=t.box2box_minmax(e.box,n.max);return ki.Utils.LE(o,s)});return s=t.minmax_tree_process_level(e,a,s,o)}static minmax_tree(e,n,s){let o=new Ma,i=[n.index.root],r=s<Number.POSITIVE_INFINITY?s*s:Number.POSITIVE_INFINITY;return r=t.minmax_tree_process_level(e,i,r,o),o}static minmax_tree_calc_distance(e,n,s){let o,i;if(null!=n&&!n.isNil()){if([o,i]=t.minmax_tree_calc_distance(e,n.left,s),i)return[o,i];if(ki.Utils.LT(o[0],Math.sqrt(n.item.key.low)))return[o,!0];let[r,a]=t.distanceToArray(e,n.item.values);return ki.Utils.LT(r,o[0])&&(o=[r,a]),[o,i]=t.minmax_tree_calc_distance(e,n.right,o),[o,i]}return[s,!1]}static shape2planarSet(e,n,s=Number.POSITIVE_INFINITY){let o=[s,new ki.Segment],i=!1;if(n instanceof ki.PlanarSet){let r=t.minmax_tree(e,n,s);[o,i]=t.minmax_tree_calc_distance(e,r.root,o)}return o}static sort(t){t.sort((t,e)=>ki.Utils.LT(t[0],e[0])?-1:ki.Utils.GT(t[0],e[0])?1:0)}static distance(t,e){return t.distanceTo(e)}static distanceToArray(t,e){let n=[Number.POSITIVE_INFINITY,new ki.Segment];for(let s of e){let[e,o]=t.distanceTo(s);ki.Utils.LT(e,n[0])&&(n=[e,o])}return n}static shape2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new ki.Segment];for(let o of n){let[n,i]=t.distance(e,o.shape);ki.Utils.LT(n,s[0])&&(s=[n,i])}return s}static multiline2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new ki.Segment];for(let o of e)for(let e of n){let[n,i]=t.distance(o.shape,e.shape);ki.Utils.LT(n,s[0])&&(s=[n,i])}return s}};var{Multiline:Ya,Point:Xa,Segment:ka,Polygon:$a}=ki;function Ba(t){return new Xa(t.split(" ").map(Number))}function ja(t){return t.split(", ").map(Ba)}function Wa(t){const e=ja(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new ka(e[t],e[t+1]));return new Ya(n)}function Ha(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new $a;let s;return e.forEach((t,e)=>{let o=t.split(", ").map(t=>new Xa(t.split(" ").map(Number)));const i=n.addFace(o);0===e?s=i.orientation():i.orientation()===s&&i.reverse()}),n}function Ua(t){if(t.startsWith("POLYGON")){return Ha(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(Ha),n=new $a;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function Va(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function Ga(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}ki.isWktString=function(t){return t.startsWith("POINT")||Va(t)||t.startsWith("LINESTRING")||Ga(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},ki.parseWKT=function t(e){if(e.startsWith("POINT")){return Ba(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return ja(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return Wa(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(Wa)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return Ua(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,s=e.match(n);s[0].startsWith("GEOMETRYCOLLECTION")&&(s[0]=s[0].replace("GEOMETRYCOLLECTION (",""));return s.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return Va(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(Ba)}(e):Ga(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(Wa).reduce((t,e)=>[...t,...e],[])}(e):[]},ki.BooleanOperations=sa,ki.Relations=xa;var Za,qa,Ja,Ka=(Za=mo(),qa=1,Ja=null!=Za?Zs(Qs(Za)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Ks(e))to.call(t,o)||o===n||qs(t,o,{get:()=>e[o],enumerable:!(s=Js(e,o))||s.enumerable});return t})(!qa&&Za&&Za.__esModule?Ja:qs(Ja,"default",{value:Za,enumerable:!0}),Za)),Qa=Object.create,tc=Object.defineProperty,ec=Object.getOwnPropertyDescriptor,nc=Object.getOwnPropertyNames,sc=Object.getPrototypeOf,oc=Object.prototype.hasOwnProperty,ic=(t,e)=>function(){return e||(0,t[nc(t)[0]])((e={exports:{}}).exports,e),e.exports},rc=(t,e,n)=>(n=null!=t?Qa(sc(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of nc(e))oc.call(t,o)||o===n||tc(t,o,{get:()=>e[o],enumerable:!(s=ec(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:tc(n,"default",{value:t,enumerable:!0}),t)),ac=ic({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),cc=ic({"node_modules/kind-of/index.js"(t,e){var n=ac(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),hc=ic({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),lc=ic({"node_modules/deep-rename-keys/index.js"(t,e){var n=cc(),s=hc();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),dc=ic({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),uc=ic({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=dc(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),pc=ic({"node_modules/xml-reader/dist/reader.js"(t,e){var n=dc(),s=uc(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:fc,sin:mc,PI:gc}=Math,{tan:yc}=Math;rc(lc()),rc(pc());function xc(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var vc=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function bc(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Pc=class extends vc{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(xc(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(xc(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(xc(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Sc=t=>{const{o:e,a:n,b:s}=t;return(n.x-e.x)*(s.y-e.y)-(n.y-e.y)*(s.x-e.x)},Mc=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||Sc({o:e,a:n,b:t})>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||Sc({o:t,a:n,b:e})>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},Nc=t=>void 0!==t,Ic=class extends vc{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(Nc)),hulls:n.cells.map(t=>Mc(t,n.pts).map(t=>n.pts[t]).filter(Nc))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},_c=t=>{const{polygon:e,clearance:n,verticesOnly:s=!1}=t,o=e.points,i=o.length;if(i<3)return[];const r=new Oa(o.map(t=>_a(t.x,t.y))).orientation()===wi.CCW,a=[];for(let t=0;t<i;t++){const e=o[t],s=o[(t+1)%i],c=Ca(s.x-e.x,s.y-e.y);if(0===c.length){a.push(wa(_a(e.x,e.y),Ca(1,0)));continue}const h=c.normalize(),l=r?Ca(h.y,-h.x):Ca(-h.y,h.x),d=_a(e.x+n*l.x,e.y+n*l.y);a.push(wa(d,l))}const c=[];for(let t=0;t<i;t++){const e=a[(t-1+i)%i],n=a[t],s=e.intersect(n);if(s.length>0){const t=s[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(s)return c;const h=[];for(let t=0;t<i;t++){const e=c[t],n=c[(t+1)%i],s=Ta(_a(e.x,e.y),_a(n.x,n.y)).length,o=Math.max(2,Math.ceil(s/20));for(let t=0;t<o;t++){const s=t/o;h.push({x:e.x+s*(n.x-e.x),y:e.y+s*(n.y-e.y)})}}return h},Cc=t=>{const{localX:e,localY:n,rect:s}=t,o=Math.cos(s.ccwRotation),i=Math.sin(s.ccwRotation);return{x:s.center.x+e*o-n*i,y:s.center.y+e*i+n*o}},Tc=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=24}=t,a=[],{minX:c,maxX:h,minY:l,maxY:d}=e;a.push({x:c,y:l},{x:h,y:l},{x:h,y:d},{x:c,y:d});for(let t=1;t<10;t++){const e=t/10;a.push({x:c+e*(h-c),y:l}),a.push({x:h,y:l+e*(d-l)}),a.push({x:h-e*(h-c),y:d}),a.push({x:c,y:d-e*(d-l)})}for(const t of n){const e=t.diameter/2+s;for(let n=0;n<r;n++){const s=2*Math.PI*n/r;a.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let s=0;s<o;s++){const i=s/o;a.push(Cc({localX:2*i*e-e,localY:-n,rect:t})),a.push(Cc({localX:e,localY:2*i*n-n,rect:t})),a.push(Cc({localX:e-2*i*e,localY:n,rect:t})),a.push(Cc({localX:-e,localY:n-2*i*n,rect:t}))}}for(const t of i){if(t.points.length<3)continue;const e=_c({polygon:t,clearance:s});a.push(...e)}return a.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},Ec=(t,e,n)=>{const s=e.length;e.push(...t);const o=t.length;for(let t=0;t<o;t++)n.push([s+t,s+(t+1)%o])},wc=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=8}=t,a=[],c=[],h=[],{minX:l,maxX:d,minY:u,maxY:p}=e,f=10,m=[];for(let t=0;t<f;t++){const e=t/f;m.push({x:l+e*(d-l),y:u})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d,y:u+e*(p-u)})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d-e*(d-l),y:p})}for(let t=0;t<f;t++){const e=t/f;m.push({x:l,y:p-e*(p-u)})}h.push(c.length),Ec(m,a,c);for(const t of n){const e=t.diameter/2+s,n=[];for(let s=0;s<r;s++){const o=2*Math.PI*s/r;n.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}h.push(c.length),Ec(n,a,c)}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=[Cc({localX:-e,localY:-n,rect:t}),Cc({localX:e,localY:-n,rect:t}),Cc({localX:e,localY:n,rect:t}),Cc({localX:-e,localY:n,rect:t})];h.push(c.length),Ec(o,a,c)}for(const t of i){if(t.points.length<3)continue;const e=_c({polygon:t,clearance:s,verticesOnly:!0});h.push(c.length),Ec(e,a,c)}const g=((t,e,n)=>{const s=new Array(e.length);for(let t=0;t<e.length;t++)for(let e=n.length-1;e>=0;e--)if(t>=n[e]){s[t]=e;break}const o=new Map,i=t.slice();for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++){if(s[t]===s[n])continue;const[r,a]=e[t],[c,h]=e[n],l=i[r],d=i[a],u=i[c],p=i[h],f=d.x-l.x,m=d.y-l.y,g=p.x-u.x,y=p.y-u.y,x=f*y-m*g;if(Math.abs(x)<1e-10)continue;const v=((u.x-l.x)*y-(u.y-l.y)*g)/x,b=((u.x-l.x)*m-(u.y-l.y)*f)/x;if(v>1e-6&&v<.999999&&b>1e-6&&b<.999999){const e=l.x+v*f,s=l.y+v*m,r=i.length;i.push({x:e,y:s}),o.has(t)||o.set(t,[]),o.get(t).push({t:v,idx:r}),o.has(n)||o.set(n,[]),o.get(n).push({t:b,idx:r})}}if(0===o.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const r=[];for(let t=0;t<e.length;t++){const n=o.get(t);if(!n||0===n.length){r.push(e[t]);continue}n.sort((t,e)=>t.t-e.t);const[s,i]=e[t];let a=s;for(const t of n)r.push([a,t.idx]),a=t.idx;r.push([a,i])}return{pts:i,constraintEdges:r,hadCrossings:!0}})(a,c,h);return{pts:g.pts.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:g.constraintEdges,hadCrossings:g.hadCrossings}},Rc=class extends vc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];if(!1!==this.input.useConstrainedDelaunay){const s=wc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments});this.output={pts:s.pts,constraintEdges:s.constraintEdges,hadCrossings:s.hadCrossings}}else this.output={pts:Tc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments})};this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},Oc=t=>{const{p:e,a:n,b:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(r<1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*o+(e.y-n.y)*i)/r;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*o,e.y-n.y-a*i)},Ac=(t,e)=>{if(t.length<=3)return 0;const n=Mc(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,Oc({p:t,a:n,b:s})))}i=Math.max(i,r)}return i},zc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Dc=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(zc(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(zc(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(zc(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},Lc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Fc=class extends vc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=(t=>{const{triangles:e,pts:n,concavityTolerance:s}=t;if(!e.length)return{cells:[],depths:[]};const o=e.map(([t,e,s])=>{const o=n[t],i=n[e],r=n[s];return o&&i&&r&&Sc({o:o,a:i,b:r})<0?[t,s,e]:[t,e,s]});let i=!0,r=0;for(;i&&r++<800;){i=!1;const t=new Map,e=o.map(()=>new Set);for(let n=0;n<o.length;n++){const s=o[n];if(s)for(let o=0;o<s.length;o++){const i=s[o],r=s[(o+1)%s.length];if(void 0===i||void 0===r)continue;const a=Lc(i,r);if(t.has(a)){const s=t.get(a);void 0!==s&&(e[n]?.add(s),e[s]?.add(n))}else t.set(a,n)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<o.length;t++){const i=e[t];if(i)for(const e of i){if(e<=t)continue;const i=Dc(o[t]??[],o[e]??[]);if(!i)continue;const l=Ac(i,n);l<=s+1e-6&&l<h&&(h=l,r=t,a=e,c=i)}}if(r<0||a<0||!c)break;o[r]=c,o.splice(a,1),i=!0}const a=o.map(t=>Ac(t,n));return{cells:o,depths:a}})({triangles:this.input.validTris,pts:this.input.pts,concavityTolerance:this.input.concavityTolerance});this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},Yc=t=>{const{a:e,b:n,c:s}=t,o=2*(e.x*(n.y-s.y)+n.x*(s.y-e.y)+s.x*(e.y-n.y));if(Math.abs(o)<1e-10)return{x:0,y:0,r2:1e18};const i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=s.x*s.x+s.y*s.y,c=(i*(n.y-s.y)+r*(s.y-e.y)+a*(e.y-n.y))/o,h=(i*(s.x-n.x)+r*(e.x-s.x)+a*(n.x-e.x))/o;return{x:c,y:h,r2:(e.x-c)**2+(e.y-h)**2}},Xc=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),kc=t=>{const{px:e,py:n,polygonPoints:s,clearance:o}=t;if(s.length<3)return!1;const i=s.map(t=>_a(t.x,t.y)),r=[];for(let t=0;t<i.length;t++){const e=i[t],n=i[(t+1)%i.length];r.push(Ta(e,n))}const a=new Oa;a.addFace(r);const c=_a(e,n);if(a.contains(c))return!0;const[h]=a.distanceTo(c);return h<o-.1},$c=t=>{const{triangles:e,pts:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t;return e.filter(([t,e,c])=>{const h=n[t],l=n[e],d=n[c];if(!h||!l||!d)return!1;if(!(t=>{const{px:e,py:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t,{minX:c,maxX:h,minY:l,maxY:d}=s;if(e<c-.1||e>h+.1||n<l-.1||n>d+.1)return!1;for(const t of o){const s=t.diameter/2+i;if((e-t.center.x)**2+(n-t.center.y)**2<s*s-.1)return!1}for(const t of r){const s=t.width/2+i,o=t.height/2+i,r=e-t.center.x,a=n-t.center.y,c=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<o-.1)return!1}for(const t of a)if(kc({px:e,py:n,polygonPoints:t.points,clearance:i}))return!1;return!0})({px:(h.x+l.x+d.x)/3,py:(h.y+l.y+d.y)/3,bounds:s,vias:o,clearance:i,rects:r,polygons:a}))return!1;if(a.length>0){const t=[h,l,d,{x:(h.x+l.x)/2,y:(h.y+l.y)/2},{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2}];for(const e of t)for(const t of a)if(kc({px:e.x,py:e.y,polygonPoints:t.points,clearance:i}))return!1}return!0})},Bc=class extends vc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];let s;if(!1!==this.input.useConstrainedDelaunay&&this.input.constraintEdges){const o=((t,e)=>{const n=t.map(t=>[t.x,t.y]);return(0,Ka.default)(n,e,{exterior:!1})})(this.input.pts,this.input.constraintEdges);s=this.input.hadCrossings?$c({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n}):o}else{const o=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:Yc({a:h,b:l,c:d})}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&Xc(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:Yc({a:e,b:n,c:t})})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts);s=$c({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n})}this.output={pts:this.input.pts,validTris:s},this.stats={validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},jc=class extends Pc{pipelineDef=[bc("generatePoints",Rc,t=>[t.inputProblem]),bc("triangulate",Bc,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,polygons:t.inputProblem.polygons,clearance:t.inputProblem.clearance,useConstrainedDelaunay:t.inputProblem.useConstrainedDelaunay,constraintEdges:e.constraintEdges,hadCrossings:e.hadCrossings}]}),bc("mergeCells",Fc,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),bc("buildRegions",Ic,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();if(!t)return{points:[],lines:[],rects:[],circles:[],texts:[]};const e=(this.inputProblem.polygons??[]).flatMap(t=>{const e=t.points;return e.map((t,n)=>{const s=e[(n+1)%e.length];return{points:[{x:t.x,y:t.y},{x:s.x,y:s.y}],strokeColor:"#ff9f43",strokeWidth:2}})}),n=(this.inputProblem.rects??[]).flatMap(t=>{const e=t.width/2,n=t.height/2,s=Math.cos(t.ccwRotation),o=Math.sin(t.ccwRotation),i=[{lx:-e,ly:-n},{lx:e,ly:-n},{lx:e,ly:n},{lx:-e,ly:n}].map(({lx:e,ly:n})=>({x:t.center.x+e*s-n*o,y:t.center.y+e*o+n*s}));return i.map((t,e)=>{const n=i[(e+1)%i.length];return{points:[{x:t.x,y:t.y},{x:n.x,y:n.y}],strokeColor:"#ff6b6b",strokeWidth:2}})});return{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:[...t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),...e,...n],rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}}};function Wc(t,e,n,s,o){const i=e.x-t.x,r=e.y-t.y,a=s.x-n.x,c=s.y-n.y,h=i*c-r*a,l=Math.sqrt(i*i+r*r),d=Math.sqrt(a*a+c*c);if(l<o||d<o)return!1;if(Math.abs(h)/(l*d)>o)return!1;const u=n.x-t.x,p=n.y-t.y;return Math.abs(i*p-r*u)/l<o}function Hc(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-12){return{t:0,distance:Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}}const r=((t.x-e.x)*s+(t.y-e.y)*o)/i,a=e.x+r*s,c=e.y+r*o;return{t:r,distance:Math.sqrt((t.x-a)**2+(t.y-c)**2)}}function Uc(t,e,n,s){const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s),a=Math.max(n,s),c=Math.max(o,r),h=Math.min(i,a);return h-c<1e-6?null:{from:c,to:h}}function Vc(t,e,n=.01){const s=[];for(let o=0;o<t.length;o++){const i=t[o],r=t[(o+1)%t.length];for(let t=0;t<e.length;t++){const o=e[t],a=e[(t+1)%e.length];if(!Wc(i,r,o,a,n))continue;const c=Hc(o,i,r),h=Hc(a,i,r);if(c.distance>n||h.distance>n)continue;const l=Uc(0,1,c.t,h.t);if(!l)continue;const d=r.x-i.x,u=r.y-i.y,p={x:i.x+l.from*d,y:i.y+l.from*u},f={x:i.x+l.to*d,y:i.y+l.to*u};s.push({from:p,to:f})}}return s}function Gc(t,e=.4){const n=t.to.x-t.from.x,s=t.to.y-t.from.y,o=Math.sqrt(n*n+s*s);if(o<.001)return[];const i=Math.max(1,Math.floor(o/e)),r=[];for(let e=0;e<i;e++){const o=(e+.5)/i;r.push({x:t.from.x+o*n,y:t.from.y+o*s})}return r}function Zc(t,e=.001){if(t.length<=1)return t;const n=[t[0]];for(let s=1;s<t.length;s++){const o=n[n.length-1],i=t[s];Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)>e&&n.push(i)}if(n.length>1){const t=n[0],s=n[n.length-1];Math.sqrt((s.x-t.x)**2+(s.y-t.y)**2)<e&&n.pop()}return n}function qc(t){let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)i.x<e&&(e=i.x),i.x>n&&(n=i.x),i.y<s&&(s=i.y),i.y>o&&(o=i.y);return{minX:e,maxX:n,minY:s,maxY:o}}function Jc(t){let e=0,n=0;for(const s of t)e+=s.x,n+=s.y;return{x:e/t.length,y:n/t.length}}function Kc(t,e,n){return{regionId:t,ports:[],d:{bounds:qc(e),center:Jc(e),polygon:e,isPad:!1,isViaRegion:n?.isViaRegion}}}function Qc(t){if(0===t.length)return[];const e=t.reduce((t,e)=>e.position.y>t.position.y?e:t),n=t.reduce((t,e)=>e.position.y<t.position.y?e:t),s=t.reduce((t,e)=>e.position.x<t.position.x?e:t),o=t.reduce((t,e)=>e.position.x>t.position.x?e:t),i={xStart:e.position.x-e.diameter/2,xEnd:e.position.x+e.diameter/2,y:e.position.y+e.diameter/2},r={xStart:n.position.x-n.diameter/2,xEnd:n.position.x+n.diameter/2,y:n.position.y-n.diameter/2},a={x:s.position.x-s.diameter/2,yStart:s.position.y-s.diameter/2,yEnd:s.position.y+s.diameter/2},c={x:o.position.x+o.diameter/2,yStart:o.position.y-o.diameter/2,yEnd:o.position.y+o.diameter/2};return Zc([{x:i.xStart,y:i.y},{x:i.xEnd,y:i.y},{x:c.x,y:c.yEnd},{x:c.x,y:c.yStart},{x:r.xEnd,y:r.y},{x:r.xStart,y:r.y},{x:a.x,y:a.yStart},{x:a.x,y:a.yEnd}])}function th(t,e,n,s){return t.map(t=>({viaId:`${s}:${t.viaId}`,diameter:t.diameter,position:{x:t.position.x+e,y:t.position.y+n}}))}function eh(t,e,n,s){return t.map(t=>({routeId:`${s}:${t.routeId}`,fromPort:`${s}:${t.fromPort}`,toPort:`${s}:${t.toPort}`,layer:t.layer,segments:t.segments.map(t=>({x:t.x+e,y:t.y+n}))}))}function nh(t,e,n){return t.map(t=>({x:t.x+e,y:t.y+n}))}function sh(t){return[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}]}function oh(t){if(t.length<3)return{top:null,bottom:null,left:null,right:null};const e=qc(t),n=.001;let s=null,o=null,i=null,r=null;for(let a=0;a<t.length;a++){const c=t[a],h=t[(a+1)%t.length];Math.abs(c.y-e.maxY)<n&&Math.abs(h.y-e.maxY)<n&&(s={x:(c.x+h.x)/2,y:e.maxY}),Math.abs(c.y-e.minY)<n&&Math.abs(h.y-e.minY)<n&&(o={x:(c.x+h.x)/2,y:e.minY}),Math.abs(c.x-e.minX)<n&&Math.abs(h.x-e.minX)<n&&(i={x:e.minX,y:(c.y+h.y)/2}),Math.abs(c.x-e.maxX)<n&&Math.abs(h.x-e.maxX)<n&&(r={x:e.maxX,y:(c.y+h.y)/2})}return{top:s,bottom:o,left:i,right:r}}function ih(t,e,n=.1){if(0===t.length)return t;const s=qc(t),o=s.minX-e.minX,i=e.maxX-s.maxX,r=s.minY-e.minY,a=e.maxY-s.maxY,c=o>0&&o<n,h=i>0&&i<n,l=r>0&&r<n,d=a>0&&a<n;if(!(c||h||l||d))return t;return Zc(t.map(t=>{let n=t.x,o=t.y;return c&&Math.abs(t.x-s.minX)<.001&&(n=e.minX),h&&Math.abs(t.x-s.maxX)<.001&&(n=e.maxX),l&&Math.abs(t.y-s.minY)<.001&&(o=e.minY),d&&Math.abs(t.y-s.maxY)<.001&&(o=e.maxY),{x:n,y:o}}))}function rh(t,e){let n=!1;const s=e.length;for(let o=0,i=s-1;o<s;i=o++){const s=e[o].x,r=e[o].y,a=e[i].x,c=e[i].y;if(Math.abs((t.y-r)*(a-s)-(t.x-s)*(c-r))<.001&&t.x>=Math.min(s,a)-.001&&t.x<=Math.max(s,a)+.001&&t.y>=Math.min(r,c)-.001&&t.y<=Math.max(r,c)+.001)return!0;if(r>t.y!=c>t.y){const e=(a-s)*(t.y-r)/(c-r)+s;t.x<e&&(n=!n)}}return n}function ah(t,e){for(const n of e)if(n.d.polygon&&rh(t,n.d.polygon))return n;return null}function ch(t){const e=t.tileWidth??t.tileSize??t.viaTile.tileWidth,n=t.tileHeight??t.tileSize??t.viaTile.tileHeight;if(void 0===e||void 0===n)throw new Error("tileWidth and tileHeight must be provided either in opts or in viaTile");const s=t.portPitch??.4,o=t.clearance??.1,i=t.concavityTolerance??0,{bounds:r,viaTile:a}=t,{viasByNet:c,routeSegments:h}=a,l=r.maxX-r.minX,d=r.maxY-r.minY,u=Math.floor(l/e),p=Math.floor(d/n),f=[],m=[],g={viasByNet:{},routeSegments:[]},y=[],x=[],v=u*e,b=p*n,P=r.minX+(l-v)/2,S=r.minY+(d-b)/2,M=P+v,N=S+b,I=e/2,_=n/2;let C=0;const T=new Set,E=(t,e,n,s)=>{const o=(i=s.x,r=s.y,`${i.toFixed(4)},${r.toFixed(4)}`);var i,r;if(T.has(o))return null;T.add(o);const a={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(a),n.ports.push(a),m.push(a),a};let w=null;if(p>0&&u>0&&(w=function(t,e,n,s,o){const i=e/2,r=n/2,a={minX:-i,maxX:i,minY:-r,maxY:r},c=[];for(const[e,n]of Object.entries(t.viasByNet)){if(0===n.length)continue;const t=Qc(n);0!==t.length&&c.push({netName:e,polygon:t,bounds:qc(t),center:Jc(t)})}const h=c.map(t=>({points:ih(t.polygon,a)})),l=new jc({bounds:a,polygons:h,clearance:s,concavityTolerance:o});l.solve();const d=l.getOutput();if(!d)throw new Error("ConvexRegionsSolver failed to compute unit tile regions");return{viaRegions:c,convexRegions:d.regions.map(t=>({polygon:t,bounds:qc(t),center:Jc(t)})),tileWidth:e,tileHeight:n}}(a,e,n,o,i)),p>0&&u>0&&w)for(let t=0;t<p;t++)for(let s=0;s<u;s++){const o=P+s*e+I,i=S+t*n+_,r=`t${t}_${s}`;for(const t of w.viaRegions){const e=nh(t.polygon,o,i),n=Kc(`${r}:v:${t.netName}`,e,{isViaRegion:!0});y.push(n),f.push(n)}for(let t=0;t<w.convexRegions.length;t++){const e=Kc(`${r}:convex:${t}`,nh(w.convexRegions[t].polygon,o,i));x.push(e),f.push(e)}for(const[t,e]of Object.entries(c)){if(0===e.length)continue;const n=th(e,o,i,r);g.viasByNet[t]||(g.viasByNet[t]=[]),g.viasByNet[t].push(...n)}g.routeSegments.push(...eh(h,o,i,r))}const R=[],O=r.maxY-N,A=S-r.minY,z=P-r.minX,D=r.maxX-M,L=Math.max(O,A)>=Math.max(z,D),F=L?r.minX:P,Y=L?r.maxX:M,X=L?r.minX:P,k=L?r.maxX:M,$=L?S:r.minY,B=L?N:r.maxY,j=L?S:r.minY,W=L?N:r.maxY;if(O>.001){const t=Y-F,e=Math.max(O,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Kc(`filler:top:${t}`,sh({minX:F+t*o,maxX:F+(t+1)*o,minY:N,maxY:r.maxY}));R.push(e),f.push(e)}}if(A>.001){const t=k-X,e=Math.max(A,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Kc(`filler:bottom:${t}`,sh({minX:X+t*o,maxX:X+(t+1)*o,minY:r.minY,maxY:S}));R.push(e),f.push(e)}}if(z>.001){const t=B-$,e=Math.max(z,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Kc(`filler:left:${t}`,sh({minX:r.minX,maxX:P,minY:$+t*o,maxY:$+(t+1)*o}));R.push(e),f.push(e)}}if(D>.001){const t=W-j,e=Math.max(D,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Kc(`filler:right:${t}`,sh({minX:M,maxX:r.maxX,minY:j+t*o,maxY:j+(t+1)*o}));R.push(e),f.push(e)}}if(w&&p>0&&u>0){const t=w.convexRegions.length;for(let e=0;e<p;e++)for(let n=0;n<u;n++){const i=(e*u+n)*t;for(let r=0;r<t;r++)for(let a=r+1;a<t;a++){const t=x[i+r],c=x[i+a],h=Vc(t.d.polygon,c.d.polygon,2*o);for(const o of h){const i=Gc(o,s);for(const s of i)E(`t${e}_${n}:convex:${r}-${a}:${C++}`,t,c,s)}}}}if(w&&p>0&&u>0){const t=w.convexRegions.length,o=w.viaRegions.length,i=Math.floor(n/s),r=[];for(let t=0;t<i;t++)r.push((t+.5)*s-_);const a=Math.floor(e/s),c=[];for(let t=0;t<a;t++)c.push((t+.5)*s-I);for(let s=0;s<p;s++)for(let i=0;i<u;i++){const a=s*u+i,h=a*t,l=a*o,d=P+i*e+I,f=S+s*n+_,m=[...x.slice(h,h+t),...y.slice(l,l+o)];if(i+1<u){const e=s*u+(i+1),n=e*t,a=e*o,c=[...x.slice(n,n+t),...y.slice(a,a+o)],h=d+I;for(const t of r){const e=f+t,n={x:h+.01,y:e},o=ah({x:h-.01,y:e},m),r=ah(n,c);o&&r&&E(`tile:${s}_${i}-${s}_${i+1}:${C++}`,o,r,{x:h,y:e})}}if(s+1<p){const e=(s+1)*u+i,n=e*t,r=e*o,a=[...x.slice(n,n+t),...y.slice(r,r+o)],h=f+_;for(const t of c){const e=d+t,n={x:e,y:h+.01},o=ah({x:e,y:h-.01},m),r=ah(n,a);o&&r&&E(`tile:${s}_${i}-${s+1}_${i}:${C++}`,o,r,{x:e,y:h})}}}}const H=new Map;for(const t of R){H.set(t.regionId,[]);const e=t.d.bounds,n=e.maxX-e.minX,i=e.maxY-e.minY,r=n>i,a=r?n:i,c=(Math.max(1,Math.floor(a/s)),2*o),h=t.regionId.startsWith("filler:top:"),l=t.regionId.startsWith("filler:bottom:"),d=t.regionId.startsWith("filler:left:"),u=t.regionId.startsWith("filler:right:"),p=[...x,...y];for(const n of p){const o=n.d.bounds,i=.001;let a,p,f=!1,m=null,g=null;if(r){const t=Math.max(e.minX,o.minX);Math.min(e.maxX,o.maxX)>t+i&&(h?(f=Math.abs(o.maxY-e.minY)<c,g=e.minY):l&&(f=Math.abs(o.minY-e.maxY)<c,g=e.maxY))}else{const t=Math.max(e.minY,o.minY);Math.min(e.maxY,o.maxY)>t+i&&(d?(f=Math.abs(o.minX-e.maxX)<c,m=e.maxX):u&&(f=Math.abs(o.maxX-e.minX)<c,m=e.minX))}if(!f)continue;r?(a=Math.max(e.minX,o.minX),p=Math.min(e.maxX,o.maxX)):(a=Math.max(e.minY,o.minY),p=Math.min(e.maxY,o.maxY));const y=p-a;if(y<i)continue;const x=Math.max(1,Math.floor(y/s)),v=y/x;for(let i=0;i<x;i++){let c;if(r){c={x:a+(i+.5)*v,y:g}}else{c={x:m,y:a+(i+.5)*v}}if(n.d.polygon){let t;if(h){const n=e.minY-o.maxY+.01;t={x:c.x,y:c.y-n}}else if(l){const n=o.minY-e.maxY+.01;t={x:c.x,y:c.y+n}}else if(d){const n=o.minX-e.maxX+.01;t={x:c.x+n,y:c.y}}else{const n=e.minX-o.maxX+.01;t={x:c.x-n,y:c.y}}if(!rh(t,n.d.polygon))continue}const u=H.get(t.regionId);u.some(t=>Math.sqrt((c.x-t.x)**2+(c.y-t.y)**2)<s)||(u.push(c),E(`filler:${n.regionId}-${t.regionId}:${C++}`,n,t,c))}}}for(let t=0;t<R.length;t++)for(let e=t+1;e<R.length;e++){const n=R[t],o=R[e],i=Vc(n.d.polygon,o.d.polygon,.01);for(const t of i){const e=Math.sqrt((t.to.x-t.from.x)**2+(t.to.y-t.from.y)**2);if(e<.01)continue;let i;i=e<s?[{x:(t.from.x+t.to.x)/2,y:(t.from.y+t.to.y)/2}]:Gc(t,s);for(const t of i)E(`filler:${n.regionId}-${o.regionId}:${C++}`,n,o,t)}}const U=f.filter(t=>!t.d.isViaRegion),V=new Set;for(const t of y){const e=oh(t.d.polygon),n=t.d.bounds,s=["top","bottom","left","right"];for(const o of s){const s=e[o];if(!s)continue;const i=`${t.regionId}:${o}`;if(V.has(i))continue;const r=.2,a=r;let c;switch(o){case"top":c={x:s.x,y:n.maxY+a};break;case"bottom":c={x:s.x,y:n.minY-a};break;case"left":c={x:n.minX-a,y:s.y};break;case"right":c={x:n.maxX+a,y:s.y}}for(const e of U){const a=e.d.bounds;let h=!1;switch(o){case"top":h=Math.abs(a.minY-n.maxY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"bottom":h=Math.abs(a.maxY-n.minY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"left":h=Math.abs(a.maxX-n.minX)<r&&a.minY<s.y&&a.maxY>s.y;break;case"right":h=Math.abs(a.minX-n.maxX)<r&&a.minY<s.y&&a.maxY>s.y}if(h&&(e.d.polygon&&rh(c,e.d.polygon))){E(`via-side:${t.regionId}:${o}:${C++}`,t,e,s),V.add(i);break}}}}return{regions:f,ports:m,viaTile:g,tileCount:{rows:p,cols:u}}}function hh(t,e=ai,n){const s=function(t){if(0===t.length)throw new Error("Cannot calculate bounds from empty connections array");let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)e=Math.min(e,i.start.x,i.end.x),n=Math.max(n,i.start.x,i.end.x),s=Math.min(s,i.start.y,i.end.y),o=Math.max(o,i.start.y,i.end.y);return{minX:e,maxX:n,minY:s,maxY:o}}(t),{regions:o,ports:i,viaTile:r,tileCount:a}=ch({viaTile:e,bounds:s,tileWidth:n?.tileWidth??e.tileWidth,tileHeight:n?.tileHeight??e.tileHeight,tileSize:n?.tileSize,portPitch:n?.portPitch,clearance:n?.clearance,concavityTolerance:n?.concavityTolerance}),c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[];for(const i of e){const{start:e,end:r,connectionId:a}=i,c=Ko(`conn:${a}:start`,e.x,e.y);n.push(c);const h=Ko(`conn:${a}:end`,r.x,r.y);n.push(h);const l=Ti({x:e.x,y:e.y,regions:t.regions});if(l){const t=Jo(`conn:${a}:start-port`,c,l.region,l.portPosition);s.push(t)}const d=Ti({x:r.x,y:r.y,regions:t.regions});if(d){const t=Jo(`conn:${a}:end-port`,h,d.region,d.portPosition);s.push(t)}const u={connectionId:a,mutuallyConnectedNetworkId:a,startRegion:c,endRegion:h};o.push(u)}return{regions:n,ports:s,connections:o}})({regions:o,ports:i},t);return{...c,viaTile:r,tileCount:a}}var lh=class extends Ln{getSolverName(){return"FixedTopologyHighDensityIntraNodeSolver"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;viaDiameter;viaTile;connMap;rootConnectionNameByConnectionId=new Map;lastActiveSubSolver=null;solvedRoutes=[];vias=[];tiledViasByNet={};constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaTile=ai,this.viaDiameter=this._resolveViaDiameter(t.viaDiameter),this.connMap=t.connMap,this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=(t=>{const e=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],n={},s=new Set;for(const e of t.portPoints)s.add(e.connectionName);let o=0;for(const t of Array.from(s))n[t]=e[o%e.length],o++;return n})(this.nodeWithPortPoints))}getConstructorParams(){return this.constructorParams}_getViaTileDiameter(t){for(const e of Object.values(t.viasByNet))if(e.length>0)return e[0].diameter;return.3}_resolveViaDiameter(t){const e=this._getViaTileDiameter(this.viaTile);return void 0!==t&&Math.abs(t-e)<=1e-6?t:e}_initializeGraph(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=t.get(e.connectionName);n?n.points.push(e):t.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.rootConnectionNameByConnectionId.clear();const e=[];for(const[n,s]of t.entries())s.points.length<2||(this.rootConnectionNameByConnectionId.set(n,s.rootConnectionName),e.push({connectionId:n,start:{x:s.points[0].x,y:s.points[0].y},end:{x:s.points[s.points.length-1].x,y:s.points[s.points.length-1].y}}));if(0===e.length)return null;const n=hh(e,this.viaTile);return this.tiledViasByNet=n.viaTile.viasByNet??{},new _i({inputGraph:{regions:n.regions,ports:n.ports},inputConnections:n.connections,viaTile:n.viaTile})}_step(){let t=this.activeSubSolver;if(!t){if(t=this._initializeGraph(),!t)return void(this.solved=!0);this.activeSubSolver=t,this.lastActiveSubSolver=t}t.step(),t.solved?(this._processResults(t),this.lastActiveSubSolver=t,this.activeSubSolver=null,this.solved=!0):t.failed&&(this.error=t.error,this.lastActiveSubSolver=t,this.activeSubSolver=null,this.failed=!0)}_upsertGlobalVia(t,e,n,s){const o=`${e.x.toFixed(4)},${e.y.toFixed(4)}`;t.has(o)||t.set(o,{center:{x:e.x,y:e.y},diameter:n,connectedTo:new Set}),t.get(o).connectedTo.add(s)}_upsertRouteViaRegion(t,e,n,s,o){t.some(t=>Math.abs(t.center.x-e.x)<.01&&Math.abs(t.center.y-e.y)<.01)||t.push({viaRegionId:o,center:{x:e.x,y:e.y},diameter:n,connectedTo:[s]})}_appendRoutePoint(t,e){const n=t[t.length-1];n&&Math.abs(n.x-e.x)<=1e-6&&Math.abs(n.y-e.y)<=1e-6&&n.z===e.z||t.push(e)}_parseViaRegionNetName(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}_parseViaRegionTilePrefix(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}_selectViasForTraversedRegion(t,e){const n=this._parseViaRegionNetName(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=this._parseViaRegionTilePrefix(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}_findNearestVia(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=t*t+i*i;r<s&&(s=r,n=o)}return n}_getBottomRoutePointsBetweenVias(t,e,n,s){if(n.viaId===s.viaId)return[n.position];const o=new Set(e.map(t=>t.viaId)),i=t.routeSegments.filter(t=>"bottom"===t.layer&&t.segments.length>=2&&o.has(t.fromPort)&&o.has(t.toPort)),r=new Map,a=(t,e,n)=>{r.has(t)||r.set(t,[]),r.get(t).push({to:e,points:n})};for(const t of i)a(t.fromPort,t.toPort,t.segments),a(t.toPort,t.fromPort,[...t.segments].reverse());const c=[n.viaId],h=new Set([n.viaId]),l=new Map;for(;c.length>0;){const t=c.shift();if(t===s.viaId)break;for(const e of r.get(t)??[])h.has(e.to)||(h.add(e.to),l.set(e.to,{from:t,points:e.points}),c.push(e.to))}if(!l.has(s.viaId))return null;const d=[];let u=s.viaId;for(;u!==n.viaId;){const t=l.get(u);if(!t)return null;d.push(t.points),u=t.from}d.reverse();const p=[];for(const t of d)for(const e of t){const t=p[p.length-1];(!t||Math.abs(t.x-e.x)>1e-6||Math.abs(t.y-e.y)>1e-6)&&p.push(e)}return p.length>0?p:null}_appendViaUsage(t,e,n,s,o){o&&(this._upsertGlobalVia(t,o.position,o.diameter,n),this._upsertRouteViaRegion(e,o.position,o.diameter,n,s))}_processResults(t){this.solvedRoutes=[];const e=t.viaTile,n=new Map;for(const s of t.solvedRoutes){const t=s.connection.connectionId,o=this.rootConnectionNameByConnectionId.get(t),i=[],r=[],a=s.path;if(0===a.length)continue;const c=a[0].port;this._appendRoutePoint(i,{x:c.d.x,y:c.d.y,z:0});for(let s=1;s<a.length;s++){const o=a[s-1],c=a[s],h={x:o.port.d.x,y:o.port.d.y},l={x:c.port.d.x,y:c.port.d.y},d=c.lastRegion;if(!d?.d?.isViaRegion||!e){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const u=this._selectViasForTraversedRegion(e,d);if(0===u.length){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const p=this._findNearestVia(u,h),f=this._findNearestVia(u,l);if(!p||!f){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const m=this._getBottomRoutePointsBetweenVias(e,u,p,f);if(m&&0!==m.length){this._appendViaUsage(n,r,t,d.regionId,p),this._appendViaUsage(n,r,t,d.regionId,f),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:0}),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:1});for(const t of m)this._appendRoutePoint(i,{x:t.x,y:t.y,z:1});this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:1}),this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:0}),this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}else this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}const h=r.map(t=>({x:t.center.x,y:t.center.y}));this.solvedRoutes.push({connectionName:t,rootConnectionName:o,traceThickness:this.traceWidth,viaDiameter:r.length>0?Math.max(...r.map(t=>t.diameter)):this.viaDiameter,route:i,vias:h,viaRegions:r})}let s=0;this.vias=Array.from(n.values()).map(t=>({viaRegionId:"via_"+s++,center:t.center,diameter:t.diameter,connectedTo:Array.from(t.connectedTo)}))}getOutput(){return this.solvedRoutes}getOutputVias(){return this.vias}visualize(){return this.activeSubSolver?this.activeSubSolver.visualize():this.lastActiveSubSolver?this.lastActiveSubSolver.visualize():super.visualize()}},dh=class extends is{getSolverName(){return"HyperSingleIntraNodeSolver"}constructorParams;solvedRoutes=[];nodeWithPortPoints;connMap;constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.connMap=t.connMap,this.constructorParams=t,this.MAX_ITERATIONS=3e7,this.GREEDY_MULTIPLIER=5,this.MIN_SUBSTEPS=100}getCombinationDefs(){return[["multiHeadPolyLine"],["majorCombinations","orderings6","cellSizeFactor"],["noVias"],["orderings50"],["flipTraceAlignmentDirection","orderings6"],["closedFormSingleTrace"],["highDensityA01"],["fixedTopologyHighDensityIntraNodeSolver"]]}getHyperParameterDefs(){return[{name:"majorCombinations",possibleValues:[{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:2,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:10,MISALIGNED_DIST_PENALTY_FACTOR:5},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:.5,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:2},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:10,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:10,VIA_PENALTY_FACTOR_2:1}]},{name:"orderings6",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5}]},{name:"cellSizeFactor",possibleValues:[{CELL_SIZE_FACTOR:.5},{CELL_SIZE_FACTOR:1}]},{name:"flipTraceAlignmentDirection",possibleValues:[{FLIP_TRACE_ALIGNMENT_DIRECTION:!0}]},{name:"noVias",possibleValues:[{CELL_SIZE_FACTOR:2,VIA_PENALTY_FACTOR_2:10}]},{name:"orderings50",possibleValues:Array.from({length:50},(t,e)=>({SHUFFLE_SEED:100+e}))},{name:"closedFormSingleTrace",possibleValues:[{CLOSED_FORM_SINGLE_TRANSITION:!0}]},{name:"multiHeadPolyLine",possibleValues:[{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:.05},{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:-.05,ITERATION_PENALTY:1e4,MINIMUM_FINAL_ACCEPTANCE_GAP:.001}]},{name:"highDensityA01",possibleValues:[{HIGH_DENSITY_A01:!0}]},{name:"fixedTopologyHighDensityIntraNodeSolver",possibleValues:[{FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER:!0}]}]}computeG(t){return t instanceof Gs?t.iterations/1e6:t?.hyperParameters?.MULTI_HEAD_POLYLINE_SOLVER?1e3+((t.hyperParameters?.ITERATION_PENALTY??0)+t.iterations)/1e4+1e4*(t.hyperParameters.SEGMENTS_PER_POLYLINE-3):t.iterations/1e4}computeH(t){return 1-(t.progress||0)}generateSolver(t){if(t.HIGH_DENSITY_A01){const e=new Gs({nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:.1,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,traceThickness:this.constructorParams.traceWidth??.15,hyperParameters:{shuffleSeed:t.SHUFFLE_SEED??0}});return e.MAX_ITERATIONS=1e7,e}return t.CLOSED_FORM_TWO_TRACE_SAME_LAYER?new as({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?new vs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_SINGLE_TRANSITION?new bs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.MULTI_HEAD_POLYLINE_SOLVER?new Vs({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,hyperParameters:t,viaDiameter:this.constructorParams.viaDiameter}):t.FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER?new lh({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,colorMap:this.constructorParams.colorMap,viaDiameter:this.constructorParams.viaDiameter,traceWidth:this.constructorParams.traceWidth}):new os({...this.constructorParams,hyperParameters:t})}onSolve(t){let e;e=t.solver instanceof Gs?t.solver.getOutput():t.solver.solvedRoutes,this.solvedRoutes=e.map(t=>{const e=this.nodeWithPortPoints.portPoints.find(e=>e.connectionName===t.connectionName);return e?.rootConnectionName?{...t,rootConnectionName:e.rootConnectionName}:t})}},uh=class extends Ln{getSolverName(){return"HighDensitySolver"}unsolvedNodePortPoints;routes;colorMap;defaultViaDiameter=.3;defaultTraceThickness=.15;viaDiameter;traceWidth;failedSolvers;activeSubSolver=null;connMap;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:s,traceWidth:o}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.routes=[],this.failedSolvers=[],this.MAX_ITERATIONS=5e7,this.viaDiameter=s??this.defaultViaDiameter,this.traceWidth=o??this.defaultTraceThickness}_step(){if(this.updateCacheStats(),this.activeSubSolver)return this.activeSubSolver.step(),this.activeSubSolver.solved?(this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null),void this.updateCacheStats();if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length>0?(this.solved=!1,this.failed=!0,this.error=`Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0,5).map(t=>t.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`,void this.updateCacheStats()):(this.solved=!0,void this.updateCacheStats());const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new dh({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth}),this.updateCacheStats()}updateCacheStats(){const t=Me();this.stats.intraNodeCacheHits=t.cacheHits,this.stats.intraNodeCacheMisses=t.cacheMisses}visualize(){let t={lines:[],points:[],rects:[],circles:[]};for(const e of this.routes){const n=Wn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:In(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});for(const n of e.vias)t.circles.push({center:n,layer:"z0,1",radius:e.viaDiameter/2,fill:this.colorMap[e.connectionName],label:`${e.connectionName} via`})}for(const e of this.failedSolvers){const n=e.nodeWithPortPoints,s=.1*n.width,o=.1*n.height;t.rects.push({center:{x:n.center.x-s/2,y:n.center.y-o/2},layer:"did_not_connect",width:s,height:o,fill:"red",label:`Failed: ${n.capacityMeshNodeId}`});const i={};for(const t of n.portPoints)i[t.connectionName]||(i[t.connectionName]=[]),i[t.connectionName].push({x:t.x,y:t.y,z:t.z});for(const[e,n]of Object.entries(i))for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1];t.lines.push({points:[s,o],strokeColor:"red",strokeDash:"10, 5",layer:"did_not_connect"})}}return this.activeSubSolver&&(t=jn(t,this.activeSubSolver.visualize())),t}};function ph(t,e){const n=[],s=e.filter(t=>t._containsTarget),o=new Map;for(const i of t.connections){const t=[];for(const n of i.pointsToConnect){let o=e[0],i=Number.MAX_VALUE;for(const t of s){const e=Math.sqrt((t.center.x-n.x)**2+(t.center.y-n.y)**2);e<i&&(i=e,o=t)}t.push(o)}if(t.length<2)throw new Error(`Not enough nodes for connection "${i.name}", only ${t.length} found`);o.set(i.name,t.map(t=>t.capacityMeshNodeId)),n.push({connection:i,nodeIds:[t[0].capacityMeshNodeId,t[t.length-1].capacityMeshNodeId],straightLineDistance:k(t[0].center,t[t.length-1].center)})}return{unshuffledConnectionsWithResults:n,connectionNameToGoalNodeIds:o}}function fh(t,e){const n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=e.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0),o=s.length>0?s.reduce((t,e)=>t+e,0)/s.length:1,i=e.filter(t=>t._offBoardConnectionId),r=new Map,a=new Map,c=new Map;for(const t of e)a.set(t.capacityMeshNodeId,[]),c.set(t.capacityMeshNodeId,[]);for(const t of e)for(const e of t.portPoints){r.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=a.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}=ph(t,e);return{nodeMap:n,avgNodePitch:o,offBoardNodes:i,portPointMap:r,nodePortPointsMap:a,nodeAssignedPortPoints:c,unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}}function mh(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function gh(t,e,n=1e-6){return Math.abs(t-e)<n}function yh(t){if(t.length<2)return 0;const e=t.map(([t,e])=>t<e?[t,e]:[e,t]);let n=0;for(let t=0;t<e.length;t++){const[s,o]=e[t];for(let i=t+1;i<e.length;i++){const[t,r]=e[i];gh(s,t)||gh(s,r)||gh(o,t)||gh(o,r)||(s<t&&t<o&&o<r||t<s&&s<r&&r<o)&&n++}}return n}var xh=t=>{const e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2,i=new Map;for(const e of t.portPoints){const t=i.get(e.connectionName)??[];t.some(t=>t.x===e.x&&t.y===e.y&&t.z===e.z)||t.push({x:e.x,y:e.y,z:e.z}),i.set(e.connectionName,t)}const r=new Map,a=[];let c=0;for(const[t,h]of i){if(h.length<2)continue;const t=h[0],i=h[1],l=mh(t,e,n,s,o),d=mh(i,e,n,s,o);if(t.z===i.z){const e=t.z,n=r.get(e)??[];n.push([l,d]),r.set(e,n)}else c++,a.push([l,d])}let h=0;for(const[t,e]of r)h+=yh(e);return{numSameLayerCrossings:h,numEntryExitLayerChanges:c,numTransitionPairCrossings:yh(a)}},vh=(t,e=1,n={})=>{const s=n.viaDiameter??.3,o=n.obstacleMargin??.2,i=(("width"in t?t.width:t)/(s/2+o)/2)**1.1*e;return 1===t.availableZ?.length&&i>1?1:i},bh=(t,e=.5,n=16)=>{let s=0,o=t;for(;s<n;){if(vh({width:o})<=e)break;o/=2,s++}return Math.max(1,s)},Ph=(t,e,n,s)=>{if(t?._containsTarget)return 0;if(1===(t.availableZ?.length??2)&&(e>0||n>0||s>0))return 1;return((.82*e+.41*n+.2*s)/2)**1.1/vh(t)};function Sh(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=xh(n),r=Math.min(Ph(t,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings),o);s+=Math.log(1-r)}return s}function Mh(t,e){if(e._containsTarget)return 0;const n=xh(t);return Ph(e,n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}function Nh(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}var Ih=1.6*3.2,_h=(t,e)=>{const n=Math.ceil(e/2),s=Math.min(t.width,t.height),o=Math.max(t.width,t.height),i=(Math.floor(s/1.6)+.1)*(Math.floor(o/3.2)+.1)/Ih;return Math.min(1,n/i)};function Ch(t,e,n,s){const o=e.x-n/2,i=e.x+n/2,r=e.y-s/2,a=e.y+s/2,c=Math.abs(t.y-a),h=Math.abs(t.x-i),l=Math.abs(t.y-r),d=Math.abs(t.x-o),u=Math.min(c,h,l,d);return u>.001?"interior":u===c?"top":u===h?"right":u===l?"bottom":"left"}function Th(t,e,n,s,o){const i=Ch(t,n,s,o),r=Ch(e,n,s,o);return"interior"!==i&&i===r}function Eh(t,e,n,s,o){const i=Ch(t,n,s,o);let r;if("top"===i||"bottom"===i){const n=s;r=Math.abs(e.x-t.x)/n}else{const n=o;r=Math.abs(e.y-t.y)/n}r=Math.min(1,Math.max(0,r));const a=(t.x+e.x)/2,c=(t.y+e.y)/2;return{x:a+(n.x-a)*r,y:c+(n.y-c)*r}}function wh(t){return"computeNodePf"in t&&"function"==typeof t.computeNodePf}function Rh(t){const e={lines:[],points:[],rects:[],circles:[]};for(const n of t.inputNodes){let s=0,o=0,i={numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},r=0;if(wh(t)){s=t.computeNodePf(n),o=t.nodeMemoryPfMap.get(n.capacityMeshNodeId)??0;const e=t.buildNodeWithPortPointsForCrossing(n);i=xh(e);const a=new Set,c=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[];for(const t of c)t.connectionName&&a.add(t.connectionName);r=a.size}else{s=t.nodePfMap.get(n.capacityMeshNodeId)??0;const e=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[],o={capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:e,availableZ:n.availableZ};i=xh(o);const a=new Set;for(const t of e)t.connectionName&&a.add(t.connectionName);r=a.size}const a=Math.min(255,Math.floor(512*s)),c=Math.max(0,255-Math.floor(512*s));let h=`rgba(${a}, ${c}, ${c}, ${s<.001?"0.1":"0.3"})`;n._containsObstacle&&(h="rgba(255, 0, 0, 0.3)"),n._offBoardConnectedCapacityMeshNodeIds?.length&&(h="rgba(255, 165, 0, 0.3)"),e.rects.push({center:n.center,width:n.width-.2,height:n.height-.2,layer:`z${n.availableZ.join(",")}`,fill:h,label:`${n.capacityMeshNodeId}\npf: ${s.toFixed(3)}, memPf: ${o.toFixed(3)}\nC#: ${r}\nxSame: ${i.numSameLayerCrossings}, xLC: ${i.numEntryExitLayerChanges}, xTransition: ${i.numTransitionPairCrossings}\nobCmid: ${n._offBoardConnectedCapacityMeshNodeIds?.join(",")}\nobs: ${n._containsObstacle?"yes":"no"}`})}if(wh(t))for(const[n,s]of t.portPointMap){const o=t.assignedPortPoints.get(n),i=o?t.colorMap[o.connectionName]??"blue":"rgba(150, 150, 150, 0.5)";e.circles.push({center:{x:s.x,y:s.y},radius:.05,fill:i,layer:`z${s.z}`,label:[n,`conn: ${o?.connectionName}`,`cd: ${s.distToCentermostPortOnZ}`,`connects: ${s.connectionNodeIds.join(",")}`,`rootConn: ${o?.rootConnectionName}`].filter(Boolean).join("\n")})}const n=wh(t)?t.connectionsWithResults:t.connectionResults;for(const s of n){if(!s.path)continue;const n=s.connection,o=t.colorMap[n.name]??"blue",i=[];for(const t of s.path)i.push({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId});for(let n=0;n<i.length-1;n++){const s=i[n],r=i[n+1],a=s.z===r.z,c=s.z;let h;h=a?0===c?void 0:"10 5":"3 3 10";const l=s.nodeId?t.nodeMap.get(s.nodeId):null;if(l&&Th(s,r,l.center,l.width,l.height)){const t=Eh(s,r,l.center,l.width,l.height);e.lines.push({points:[{x:s.x,y:s.y},{x:t.x,y:t.y}],strokeColor:o,strokeDash:h}),e.lines.push({points:[{x:t.x,y:t.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}else e.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}}if(wh(t)&&!t.solved&&t.candidates&&t.candidates.length>0){const n=t.currentConnection,s=n?t.colorMap[n.connection.name]??"blue":"blue";if(n){const[o,i]=n.nodeIds,r=t.nodeMap.get(o),a=t.nodeMap.get(i),c=n.connection.pointsToConnect[0],h=n.connection.pointsToConnect[n.connection.pointsToConnect.length-1];if(r&&a){const t=c?{x:c.x,y:c.y}:r.center,o=h?{x:h.x,y:h.y}:a.center;e.lines.push({points:[t,o],strokeColor:In(s,.5),strokeDash:"5 5"}),e.points.push({x:t.x,y:t.y,color:s,label:[`Start: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.points.push({x:o.x,y:o.y,color:s,label:[`End: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.circles.push({center:o,radius:.08,stroke:s,label:`Goal: ${n.connection.name}`})}}const o=[...t.candidates].sort((t,e)=>t.f-e.f).slice(0,1);for(const i of o){const o=[];let r=i;for(;r;)o.unshift({x:r.point.x,y:r.point.y,z:r.z,lastMoveWasOffBoard:r.lastMoveWasOffBoard,nodeId:r.currentNodeId}),r=r.prevCandidate;for(let n=0;n<o.length-1;n++){const i=o[n],r=o[n+1],a=i.z===r.z,c=i.z;let h;h=r.lastMoveWasOffBoard?"2 2":a?0===c?void 0:"10 5":"3 3 10";const l=i.nodeId?t.nodeMap.get(i.nodeId):null,d=.02*i.z;if(l&&Th(i,r,l.center,l.width,l.height)){const t=Eh(i,r,l.center,l.width,l.height);e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:t.x+d,y:t.y+d}],strokeColor:In(s,.25),strokeDash:h}),e.lines.push({points:[{x:t.x+d,y:t.y+d},{x:r.x+d,y:r.y+d}],strokeColor:In(s,.25),strokeDash:h})}else e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:r.x+d,y:r.y+d}],strokeColor:In(s,.25),strokeDash:h})}if(o.length>=1){const r=o[o.length-1];let a=0,c=0,h=0,l=0,d=0,u=0;const p=t.nodeMap.get(i.prevCandidate?.currentNodeId);if(p&&i.prevCandidate&&i.portPoint&&n){const e=n.connection.name,s={x:i.prevCandidate.point.x,y:i.prevCandidate.point.y,z:i.prevCandidate.z,connectionName:e},o={x:i.portPoint.x,y:i.portPoint.y,z:i.portPoint.z,connectionName:e},r=t.buildNodeWithPortPointsForCrossing(p,[s,o]),f=Ns(r);h=f.numSameLayerCrossings,l=f.numTransitionPairCrossings,d=f.numEntryExitLayerChanges;const m=t.capacityMeshNodeMap.get(p.capacityMeshNodeId);m&&(c=t.JUMPER_PF_FN_ENABLED&&1===p.availableZ.length?_h(m,h):Ph(m,h,d,l),a=c**2*t.NODE_PF_FACTOR),u=i.prevCandidate.g>0?i.g-i.prevCandidate.g:i.g}if(!n)continue;const[f,m]=n.nodeIds,g=t.nodeMap.get(m),y=g?Math.sqrt((r.x-g.center.x)**2+(r.y-g.center.y)**2):0,x=t.avgNodePitch>0?y/t.avgNodePitch:0,v=x*t.BASE_CANDIDATE_COST,b=t.nodeMemoryPfMap.get(i.currentNodeId)??0,P=-Math.log(1-b)*t.MEMORY_PF_FACTOR;e.circles.push({center:r,radius:.03,fill:In(s,.25),layer:`z${i.z}`,label:[`f: ${i.f.toFixed(2)}`,`g: ${i.g.toFixed(2)} (nodeDelta: ${u.toFixed(2)})`,`h: ${i.h.toFixed(2)}`,` dist: ${y.toFixed(2)}`,` estHops: ${x.toFixed(1)}`,` estStepCost: ${v.toFixed(2)}`,` memRiskCost: ${P.toFixed(2)}`,`z: ${i.z}`,`node: ${i.currentNodeId}`,`Cost(Pf): ${a.toFixed(3)}`,`Pf: ${c.toFixed(3)}`,`xSame: ${h}, xTrans: ${l}, xLC: ${d}`,`routeOffBoard=${t.currentConnectionShouldRouteOffBoard}`,`offBoardTouched=${i.hasTouchedOffBoardNode??!1}`,`lastMoveWasOffBoard=${i.lastMoveWasOffBoard??!1}`].join("\n")})}}}return e}function Oh(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=xh(n),r=Math.min(_h(t,i.numSameLayerCrossings),o);s+=Math.log(1-r)}return s}var Ah=class extends Ln{constructor(t){super(),this.input=t;const{simpleRouteJson:e,capacityMeshNodes:n,inputNodes:s,colorMap:o,nodeMemoryPfMap:i,hyperParameters:r,precomputedInitialParams:a,fixedRoutes:c}=t;if(this.input=structuredClone(t),this.MAX_ITERATIONS=1e8,this.simpleRouteJson=e,this.inputNodes=s,this.colorMap=o??{},this.capacityMeshNodeMap=new Map(n.map(t=>[t.capacityMeshNodeId,t])),this.nodeMemoryPfMap=i??new Map,this.hyperParameters=r??{},a){this.nodeMap=a.nodeMap,this.avgNodePitch=a.avgNodePitch,this.offBoardNodes=a.offBoardNodes,this.portPointMap=a.portPointMap,this.nodePortPointsMap=a.nodePortPointsMap,this.connectionNameToGoalNodeIds=a.connectionNameToGoalNodeIds;const{nodeAssignedPortPoints:t}=function(t){const e=new Map;for(const[n,s]of t.nodeAssignedPortPoints)e.set(n,[...s]);return{nodeAssignedPortPoints:e}}(a);this.nodeAssignedPortPoints=t,this.connectionsWithResults=Gn(structuredClone(a.unshuffledConnectionsWithResults),this.hyperParameters.SHUFFLE_SEED??0)}else{this.nodeMap=new Map(s.map(t=>[t.capacityMeshNodeId,t]));const t=s.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0);this.avgNodePitch=t.length>0?t.reduce((t,e)=>t+e,0)/t.length:1,this.offBoardNodes=s.filter(t=>t._offBoardConnectionId),this.portPointMap=new Map,this.nodePortPointsMap=new Map;for(const t of s)this.nodePortPointsMap.set(t.capacityMeshNodeId,[]),this.nodeAssignedPortPoints.set(t.capacityMeshNodeId,[]);for(const t of s)for(const e of t.portPoints){this.portPointMap.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=this.nodePortPointsMap.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{connectionsWithResults:e,connectionNameToGoalNodeIds:n}=this.getConnectionsWithNodes();this.connectionsWithResults=e,this.connectionNameToGoalNodeIds=n}if(c&&c.length>0)for(const t of c)if(this.connectionsWithResults.push(t),t.portPoints)for(const e of t.portPoints)e.portPointId&&this.assignedPortPoints.set(e.portPointId,{connectionName:e.connectionName,rootConnectionName:e.rootConnectionName});for(const t of this.connectionsWithResults)t.path?this.processedConnectionQueue.push(t):this.unprocessedConnectionQueue.push(t);this.totalConnectionCount=this.connectionsWithResults.length}getSolverName(){return"PortPointPathingSolver"}hyperParameters;simpleRouteJson;inputNodes;nodeMap;nodePortPointsMap;portPointMap;connectionsWithResults=[];failedConnection=null;assignedPortPoints=new Map;nodeAssignedPortPoints=new Map;PORT_POINT_REUSE_FACTOR=1e3;BASE_COST_FOR_NOT_GOING_OFF_BOARD=100;get NODE_PF_FACTOR(){return this.hyperParameters.NODE_PF_FACTOR??50}get RANDOM_WALK_DISTANCE(){return this.hyperParameters.RANDOM_WALK_DISTANCE??0}get MEMORY_PF_FACTOR(){return this.hyperParameters.MEMORY_PF_FACTOR??0}get CENTER_OFFSET_FOCUS_SHIFT(){return this.hyperParameters.CENTER_OFFSET_FOCUS_SHIFT??0}get RANDOM_COST_MAGNITUDE(){return this.hyperParameters.RANDOM_COST_MAGNITUDE??0}get BASE_CANDIDATE_COST(){return this.hyperParameters.BASE_CANDIDATE_COST??0}get NODE_PF_MAX_PENALTY(){return this.hyperParameters.NODE_PF_MAX_PENALTY??1e4}get FORCE_CENTER_FIRST(){return this.hyperParameters.FORCE_CENTER_FIRST??!0}get FORCE_OFF_BOARD_FREQUENCY(){return 0===this.offBoardNodes.length?0:this.hyperParameters.FORCE_OFF_BOARD_FREQUENCY??0}get FORCE_OFF_BOARD_SEED(){return this.hyperParameters.FORCE_OFF_BOARD_SEED??0}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.NODE_PF_MAX_PENALTY))}get CENTER_OFFSET_DIST_PENALTY_FACTOR(){return this.hyperParameters.CENTER_OFFSET_DIST_PENALTY_FACTOR??0}get STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR(){return this.hyperParameters.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR??0}colorMap;get GREEDY_MULTIPLIER(){return this.hyperParameters.GREEDY_MULTIPLIER??1.3}MAX_CANDIDATES_IN_MEMORY=5e3;get MAX_ITERATIONS_PER_PATH(){return this.hyperParameters.MAX_ITERATIONS_PER_PATH??1e4}ITERATIONS_PER_MM_FOR_PATH=30;BASE_ITERATIONS_PER_PATH=1e4;get RIPPING_ENABLED(){return this.hyperParameters.RIPPING_ENABLED??!1}get RIPPING_PF_THRESHOLD(){const t=this.hyperParameters.START_RIPPING_PF_THRESHOLD,e=this.hyperParameters.END_RIPPING_PF_THRESHOLD;if(void 0!==t&&void 0!==e){const n=this.MAX_RIPS;return t+(n>0?this.totalRipCount/n:0)*(e-t)}return this.hyperParameters.RIPPING_PF_THRESHOLD??.3}get MAX_RIPS(){return this.hyperParameters.MAX_RIPS??100}get RANDOM_RIP_FRACTION(){return this.hyperParameters.RANDOM_RIP_FRACTION??0}get JUMPER_PF_FN_ENABLED(){return this.hyperParameters.JUMPER_PF_FN_ENABLED??!1}jumpersPerMmSquared=.1;testedRipConnections=new Map;totalRipCount=0;get MIN_ALLOWED_BOARD_SCORE(){return this.hyperParameters.MIN_ALLOWED_BOARD_SCORE??-1e4}nodeMemoryPfMap;unprocessedConnectionQueue=[];processedConnectionQueue=[];currentConnection=null;totalConnectionCount=0;currentPathIterations=0;candidates;visitedPortPoints;connectionNameToGoalNodeIds;capacityMeshNodeMap;avgNodePitch;currentConnectionShouldRouteOffBoard=!1;activeCandidateStraightLineDistance;offBoardNodes=[];baseNodeCostCache=new Map;getConstructorParams(){return this.input}clearCostCaches(){this.baseNodeCostCache.clear()}clampPf(t){return Number.isFinite(t)?Math.min(Math.max(t,0),.999999):.999999}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseNodeFailureCost(t){const e=this.baseNodeCostCache.get(t);if(null!=e)return e;const n=this.nodeMap.get(t);if(!n)return 0;const s=this.computeNodePf(n),o=this.pfToFailureCost(s);return this.baseNodeCostCache.set(t,o),o}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.JUMPER_PF_FN_ENABLED?Oh(t,this.capacityMeshNodeMap):Sh(t,this.capacityMeshNodeMap)}getMaxIterationsForCurrentPath(){const t=this.activeCandidateStraightLineDistance??0;return Math.min(this.BASE_ITERATIONS_PER_PATH+this.ITERATIONS_PER_MM_FOR_PATH*t,this.MAX_ITERATIONS_PER_PATH)}getNodeDeltaFailureCostForSegment(t,e,n){const s=this.nodeMap.get(t);if(!s)return 0;const o=this.getBaseNodeFailureCost(t),i=this.computeNodePf(s,[e,n]),r=this.pfToFailureCost(i),a=Math.max(0,r-o);return i>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:a*this.NODE_PF_FACTOR}getConnectionsWithNodes(){const{unshuffledConnectionsWithResults:t,connectionNameToGoalNodeIds:e}=ph(this.simpleRouteJson,this.inputNodes);return{connectionsWithResults:Gn(t,this.hyperParameters.SHUFFLE_SEED??0),connectionNameToGoalNodeIds:e}}buildNodeWithPortPointsForCrossing(t,e){const n=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[],s=e?[...n,...e]:n;return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:s,availableZ:t.availableZ}}computeNodePf(t,e){if(t._containsTarget)return 0;const n=this.buildNodeWithPortPointsForCrossing(t,e),s=xh(n);return this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?_h(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings):Ph(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}getPortPointReusePenalty(t,e){const n=this.assignedPortPoints.get(t);return n?e===n.rootConnectionName?0:this.PORT_POINT_REUSE_FACTOR:0}getOtherNodeId(t,e){const[n,s]=t.connectionNodeIds;return n===e?s:s===e?n:null}computeG(t,e,n,s,o){const i=t.currentNodeId,r=t.point,a={x:r.x,y:r.y,z:t.z,connectionName:s,rootConnectionName:o},c={x:e.x,y:e.y,z:e.z,connectionName:s,rootConnectionName:o},h=this.getNodeDeltaFailureCostForSegment(i,a,c);return t.g+h}computeGToEndTarget(t,e,n,s){const o=t.currentNodeId,i={x:t.point.x,y:t.point.y,z:t.z,connectionName:n,rootConnectionName:s},r={x:e.x,y:e.y,z:t.z,connectionName:n,rootConnectionName:s},a=this.getNodeDeltaFailureCostForSegment(o,i,r);return t.g+a}computeDistanceToNearestOffBoardNode(t){if(0===this.offBoardNodes.length)return 1/0;let e=1/0;for(const n of this.offBoardNodes){const s=k(t,n.center);s<e&&(e=s)}return e}computeH(t,e,n,s,o,i){if(this.RANDOM_WALK_DISTANCE>0&&o<this.RANDOM_WALK_DISTANCE)return 0;if(this.currentConnectionShouldRouteOffBoard&&!i)return this.BASE_COST_FOR_NOT_GOING_OFF_BOARD+this.computeDistanceToNearestOffBoardNode(t);const r=this.nodeMap.get(n);if(!r)return 0;const a=k(t,r.center),c=this.avgNodePitch>0?a/this.avgNodePitch:0,h=this.clampPf(this.nodeMemoryPfMap.get(e)??0),l=this.pfToFailureCost(h)*this.MEMORY_PF_FACTOR,d=c*this.BASE_CANDIDATE_COST,u=this.CENTER_OFFSET_DIST_PENALTY_FACTOR*t.distToCentermostPortOnZ**2;let p=0;if(this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR>0&&this.currentConnection){const e=X(t,this.currentConnection.connection.pointsToConnect[0],this.currentConnection.connection.pointsToConnect[1]);p=this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR*e}return a+d+l+u+p}getVisitedPortPointKey(t,e){return this.currentConnectionShouldRouteOffBoard&&e?`${t}:touched_off_board`:t}getAvailableExitPortPoints(t,e){const n=this.currentConnection?.connection.rootConnectionName,s=this.nodePortPointsMap.get(t)??[],o=[];for(const t of s){const s=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(s))continue;const i=this.assignedPortPoints.get(t.portPointId);i&&i?.rootConnectionName!==n||o.push(t)}return o}getAvailableExitPortPointsWithOmissions(t,e,n){const s=this.nodePortPointsMap.get(t)??[],o=this.currentConnection?.connection.rootConnectionName,i=new Map;for(const e of s){const s=this.getVisitedPortPointKey(e.portPointId,n);if(this.visitedPortPoints?.has(s))continue;const o=this.getOtherNodeId(e,t);if(!o)continue;this.nodeMap.get(o);const r=`${o}|${e.z}`,a=i.get(r)??[];a.push(e),i.set(r,a)}const r=[];for(const[,t]of i){t.sort((t,e)=>t.distToCentermostPortOnZ-e.distToCentermostPortOnZ);const e=t[0];if(!e)continue;const n=this.assignedPortPoints.get(e.portPointId),s=n&&n.rootConnectionName===o;if(!n||s){r.push(e);continue}const i=[...t].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y),a=[];let c=[];for(const t of i){const e=this.assignedPortPoints.get(t.portPointId);!e||e.rootConnectionName===o?c.push(t):c.length>0&&(a.push(c),c=[])}c.length>0&&a.push(c);for(const t of a){const e=Math.floor(t.length/2);r.push(t[e])}}return r}getAvailableExitPortPointsForOffboardConnection(t,e){const n=this.nodeMap.get(t);if(!n)return[];const s=this.currentConnection?.connection.rootConnectionName,o=[];for(const i of n?._offBoardConnectedCapacityMeshNodeIds??[]){if(i===t)continue;if(!this.nodeMap.get(i))continue;const n=this.nodePortPointsMap.get(i)??[];for(const t of n){const n=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(n))continue;const r=this.assignedPortPoints.get(t.portPointId);r&&r.rootConnectionName!==s||o.push({...t,throughNodeId:i})}}return o}canTravelThroughObstacle(t,e,n){const s=this.connectionNameToGoalNodeIds.get(e);return s?.includes(t.capacityMeshNodeId)||Boolean(t._offBoardConnectionId)}isAtEndGoal(t,e){return t===e}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(n.lastMoveWasOffBoard&&n.throughNodeId){const t=this.nodeMap.get(n.throughNodeId),s=n.prevCandidate?this.nodeMap.get(n.prevCandidate.currentNodeId):null;e.push(n),t&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.throughNodeId,point:t.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0}),s&&s._offBoardConnectionId&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.prevCandidate.currentNodeId,point:s.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0})}else e.push(n);n=n.prevCandidate}return e.reverse()}assignPortPointsForPath(t,e,n){const s=[];for(let o=0;o<t.length;o++){const i=t[o];if(!i.portPoint){const r=0===o,a=o===t.length-1;if(!r&&!a){const t={x:i.point.x,y:i.point.y,z:i.z,connectionName:e,rootConnectionName:n};s.push(t);const o=this.nodeAssignedPortPoints.get(i.currentNodeId)??[];o.push(t),this.nodeAssignedPortPoints.set(i.currentNodeId,o)}continue}const r=i.portPoint;this.assignedPortPoints.set(r.portPointId,{connectionName:e,rootConnectionName:n});const a={portPointId:r.portPointId,x:r.x,y:r.y,z:r.z,connectionName:e,rootConnectionName:n};s.push(a);for(const t of r.connectionNodeIds){const e=this.nodeAssignedPortPoints.get(t)??[];e.push(a),this.nodeAssignedPortPoints.set(t,e)}}const o=Array.from(new Set(t.map(t=>t.currentNodeId)));for(const t of o){const s=this.nodeMap.get(t);if(s&&s._offBoardConnectionId)for(const t of s?._offBoardConnectedCapacityMeshNodeIds??[]){const s=this.nodePortPointsMap.get(t)??[];for(const t of s)this.assignedPortPoints.set(t.portPointId,{connectionName:e,rootConnectionName:n})}}return s}addTargetPointsToNodes(t,e){const n=t[0],s=t[t.length-1],o=e.pointsToConnect[0],i=e.pointsToConnect[e.pointsToConnect.length-1];if(n&&o){const t=this.nodeAssignedPortPoints.get(n.currentNodeId)??[];t.push({x:o.x,y:o.y,z:n.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(n.currentNodeId,t)}if(s&&i){const t=this.nodeAssignedPortPoints.get(s.currentNodeId)??[];t.push({x:i.x,y:i.y,z:s.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(s.currentNodeId,t)}}isPortPointInPathChain(t,e){let n=t;for(;n;){if(n.portPoint?.portPointId===e)return!0;n=n.prevCandidate}return!1}isNodeInPathChain(t,e){let n=t;for(;n;){if(n.currentNodeId===e)return!0;n=n.prevCandidate}return!1}_step(){if(this.currentConnection||(this.currentConnection=this.unprocessedConnectionQueue.shift()??null),!this.currentConnection){const t=this.computeBoardScore();return this.stats={boardScore:t,totalRipCount:this.totalRipCount},t<this.MIN_ALLOWED_BOARD_SCORE?(this.failedConnection=null,this.failed=!0,void(this.error=`Board score ${t.toFixed(2)} is less than MIN_ALLOWED_BOARD_SCORE ${this.MIN_ALLOWED_BOARD_SCORE.toFixed(2)}`)):void(this.solved=!0)}const t=this.currentConnection;this.activeCandidateStraightLineDistance=t.straightLineDistance,this.currentPathIterations++;const e=this.getMaxIterationsForCurrentPath();if(this.currentPathIterations>e)return this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,this.failed=!0,void(this.error=`Exceeded max iterations for path (${e}) on connection ${t.connection.name}`);const[n,s]=t.nodeIds,o=this.nodeMap.get(n),i=this.nodeMap.get(s);if(!o||!i)return this.processedConnectionQueue.push(t),this.currentConnection=null,void(this.currentPathIterations=0);const r=t.connection.name,a=t.connection.rootConnectionName,c=t.connection.pointsToConnect[0];if(!this.candidates){if(this.clearCostCaches(),this.FORCE_OFF_BOARD_FREQUENCY>0){const t=Un(17*(this.hyperParameters.SHUFFLE_SEED??0)+this.FORCE_OFF_BOARD_SEED+this.processedConnectionQueue.length);this.currentConnectionShouldRouteOffBoard=t()<this.FORCE_OFF_BOARD_FREQUENCY}else this.currentConnectionShouldRouteOffBoard=!1;this.candidates=[],this.visitedPortPoints=new Set;for(const t of o.availableZ){const e=c?{x:c.x,y:c.y}:o.center,i=this.computeH({...e,distToCentermostPortOnZ:0},n,s,t,0,!1),r=0+i*this.GREEDY_MULTIPLIER;this.candidates.push({prevCandidate:null,portPoint:null,currentNodeId:n,point:e,z:t,f:r,g:0,h:i,distanceTraveled:0,hasTouchedOffBoardNode:!1})}}this.candidates.sort((t,e)=>t.f-e.f);let h,l=this.candidates.shift();for(;l?.portPoint&&this.visitedPortPoints;){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);if(!this.visitedPortPoints.has(t))break;l=this.candidates.shift()}if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!l)return this.error=`Ran out of candidates on connection ${r}`,this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,void(this.failed=!0);if(l.portPoint&&this.visitedPortPoints){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);this.visitedPortPoints.add(t)}if(this.isAtEndGoal(l.currentNodeId,s)){const e=t.connection.pointsToConnect[t.connection.pointsToConnect.length-1],n=e?{x:e.x,y:e.y}:i.center,o=this.computeGToEndTarget(l,n,r,a),c={prevCandidate:l,portPoint:null,currentNodeId:s,point:n,z:l.z,g:o,h:0,f:o,distanceTraveled:l.distanceTraveled+k(l.point,n)},h=this.getBacktrackedPath(c);return t.path=h,t.portPoints=this.assignPortPointsForPath(h,r,a),this.addTargetPointsToNodes(h,t.connection),this.clearCostCaches(),this.RIPPING_ENABLED&&this.processRippingForPath(h,r),this.processedConnectionQueue.push(t),this.currentConnection=null,this.progress=this.processedConnectionQueue.length/this.totalConnectionCount,this.candidates=null,this.visitedPortPoints=null,void(this.currentPathIterations=0)}const d=this.nodeMap.get(l.currentNodeId);h=d?._offBoardConnectionId?this.getAvailableExitPortPointsForOffboardConnection(l.currentNodeId,l.hasTouchedOffBoardNode):this.FORCE_CENTER_FIRST?this.getAvailableExitPortPointsWithOmissions(l.currentNodeId,s,l.hasTouchedOffBoardNode):this.getAvailableExitPortPoints(l.currentNodeId,l.hasTouchedOffBoardNode);for(const t of h){if(this.isPortPointInPathChain(l,t.portPointId))continue;if(this.visitedPortPoints?.has(t.portPointId))continue;const e=this.getOtherNodeId(t,t.throughNodeId??l.currentNodeId);if(!e)continue;if(this.isNodeInPathChain(l,e))continue;const n="throughNodeId"in t?t.throughNodeId:void 0,o=n?this.nodeMap.get(n):null,i=this.nodeMap.get(e);if(!i)continue;if(i._containsObstacle&&!this.canTravelThroughObstacle(i,r,a))continue;const c=this.computeG(l,t,e,r,a);if(!this.RIPPING_ENABLED&&c>-this.MIN_ALLOWED_BOARD_SCORE)continue;const h=l.distanceTraveled+k(l.point,t),u=l.hasTouchedOffBoardNode||Boolean(i._offBoardConnectionId),p=this.computeH(t,e,s,t.z,h,u),f=c+p*this.GREEDY_MULTIPLIER,m=Boolean(d?._offBoardConnectionId)&&Boolean(o?._offBoardConnectionId);this.candidates.push({prevCandidate:l,portPoint:t,currentNodeId:e,point:{x:t.x,y:t.y},z:t.z,f:f,g:c,h:p,distanceTraveled:h,lastMoveWasOffBoard:m,throughNodeId:m?n:void 0,hasTouchedOffBoardNode:u||Boolean(i._offBoardConnectionId)||Boolean(d?._offBoardConnectionId)})}}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}getConnectionsInNode(t,e){const n=[],s=new Set;for(const o of this.connectionsWithResults)if(o.path&&o.connection.name!==e&&!s.has(o.connection.name))for(const e of o.path)if(e.currentNodeId===t){n.push(o),s.add(o.connection.name);break}return n}computeNodePfWithoutConnection(t,e){if(t._containsTarget)return{pf:0,totalCrossings:0};const n=(this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[]).filter(t=>t.connectionName!==e),s={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=xh(s),i=o.numSameLayerCrossings+o.numEntryExitLayerChanges+o.numTransitionPairCrossings;return{pf:Ph(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings),totalCrossings:i}}computeNodeCrossings(t){if(t._containsTarget)return 0;const e=this.buildNodeWithPortPointsForCrossing(t),n=xh(e);return n.numSameLayerCrossings+n.numEntryExitLayerChanges+n.numTransitionPairCrossings}ripConnection(t){const e=t.connection.name;for(const[t,n]of this.assignedPortPoints.entries())n.connectionName===e&&this.assignedPortPoints.delete(t);for(const[t,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(t=>t.connectionName!==e);this.nodeAssignedPortPoints.set(t,s)}t.path=void 0,t.portPoints=void 0}requeueConnection(t){this.totalRipCount++;const e=this.processedConnectionQueue.indexOf(t);if(-1!==e)return this.processedConnectionQueue.splice(e,1),this.unprocessedConnectionQueue.push(t),!0;const n=this.unprocessedConnectionQueue.indexOf(t);return-1!==n&&(this.unprocessedConnectionQueue.splice(n,1),this.unprocessedConnectionQueue.unshift(t)),!0}processRippingForPath(t,e){const n=Array.from(new Set(t.map(t=>t.currentNodeId)));let s=!1;for(const t of n){if(this.totalRipCount>this.MAX_RIPS)break;const n=this.nodeMap.get(t);if(!n)continue;let o=this.computeNodePf(n);if(o<=this.RIPPING_PF_THRESHOLD)continue;this.testedRipConnections.has(t)||this.testedRipConnections.set(t,new Set);const i=this.testedRipConnections.get(t),r=Gn(this.getConnectionsInNode(t,e),(this.hyperParameters.SHUFFLE_SEED??0)+this.processedConnectionQueue.length);for(const t of r){if(o<=this.RIPPING_PF_THRESHOLD)break;const e=t.connection.name;i.add(e);const{pf:r}=this.computeNodePfWithoutConnection(n,e);this.ripConnection(t);if(!this.requeueConnection(t))return;o=r,s=!0,this.clearCostCaches()}}s&&this.RANDOM_RIP_FRACTION>0&&this.processRandomRipping(e)}processRandomRipping(t){const e=this.processedConnectionQueue.filter(e=>void 0!==e.path&&e.connection.name!==t);if(0===e.length)return;const n=Math.max(1,Math.floor(this.RANDOM_RIP_FRACTION*e.length)),s=Gn(e,(this.hyperParameters.SHUFFLE_SEED??0)+this.totalRipCount+this.processedConnectionQueue.length);for(let t=0;t<n&&t<s.length&&!(this.totalRipCount>this.MAX_RIPS);t++){const e=s[t];this.ripConnection(e);if(!this.requeueConnection(e))return;this.clearCostCaches()}}visualize(){let t={};if(this.failed){const e=this.failedConnection?.connection.pointsToConnect[0],n=this.failedConnection?.connection.pointsToConnect[1];e&&n&&(t={lines:[{points:[e,n],label:`Failed Connection ${this.failedConnection?.connection.name}`,strokeWidth:1,strokeColor:"red",strokeDash:[2,2]}]})}return M(Rh(this),t)}},zh=class extends is{getSolverName(){return"HyperPortPointPathingSolver"}params;precomputedInitialParams;constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e8,this.GREEDY_MULTIPLIER=1.2,this.MIN_SUBSTEPS=50,this.precomputedInitialParams=t.precomputedInitialParams??fh(t.simpleRouteJson,t.inputNodes)}getHyperParameterDefs(){const t=this.params.numShuffleSeeds??50;return[{name:"SHUFFLE_SEED",possibleValues:Array.from({length:t},(t,e)=>({SHUFFLE_SEED:e+1700*(this.params.hyperParameters?.SHUFFLE_SEED??0)}))}]}getCombinationDefs(){return[["SHUFFLE_SEED"]]}generateSolver(t){return new Ah({simpleRouteJson:this.params.simpleRouteJson,capacityMeshNodes:this.params.capacityMeshNodes,inputNodes:this.params.inputNodes,colorMap:this.params.colorMap,nodeMemoryPfMap:this.params.nodeMemoryPfMap,hyperParameters:{...this.params.hyperParameters,...t,MIN_ALLOWED_BOARD_SCORE:this.params.minAllowedBoardScore??t.MIN_ALLOWED_BOARD_SCORE??this.params.hyperParameters?.MIN_ALLOWED_BOARD_SCORE},precomputedInitialParams:this.precomputedInitialParams,fixedRoutes:this.params.fixedRoutes})}computeG(t){return-t.computeBoardScore()}computeH(t){const e=t.progress||0;if(e<.1)return 0;return-(t.computeBoardScore()/e)*(1-e)}getNodesWithPortPoints(){if(this.winningSolver)return this.winningSolver.getNodesWithPortPoints();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.getNodesWithPortPoints():[]}get connectionsWithResults(){if(this.winningSolver)return this.winningSolver.connectionsWithResults;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.connectionsWithResults:[]}get inputNodes(){if(this.winningSolver)return this.winningSolver.inputNodes;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.inputNodes:this.params.inputNodes}get nodeMap(){if(this.winningSolver)return this.winningSolver.nodeMap;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeMap:new Map(this.params.inputNodes.map(t=>[t.capacityMeshNodeId,t]))}get assignedPortPoints(){if(this.winningSolver)return this.winningSolver.assignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.assignedPortPoints:new Map}get nodeAssignedPortPoints(){if(this.winningSolver)return this.winningSolver.nodeAssignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeAssignedPortPoints:new Map}computeBoardScore(){if(this.winningSolver)return this.winningSolver.computeBoardScore();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.computeBoardScore():0}onSolve(t){this.stats={...t.solver.stats,winningHyperParameters:this.winningSolver?.hyperParameters}}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function Dh(t){let e=t;return()=>{e+=1831565813;let t=e;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}var Lh=[{SHUFFLE_SEED:100,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,MEMORY_PF_FACTOR:0,EXPANSION_DEGREES:10,FORCE_CENTER_FIRST:!0,FORCE_OFF_BOARD_FREQUENCY:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0}],Fh=class extends Ln{getSolverName(){return"MultiSectionPortPointOptimizer"}simpleRouteJson;inputNodes;capacityMeshNodes;capacityMeshEdges;colorMap;nodeMap;capacityMeshNodeMap;connectionResults;assignedPortPoints;nodeAssignedPortPoints;sections=[];activeSubSolver=null;currentSection=null;sectionScoreBeforeOptimization=0;currentSectionCenterNodeId=null;currentScheduleIndex=0;nodePfMap=new Map;attemptsToFixNode=new Map;sectionAttempts=0;MAX_ATTEMPTS_PER_NODE=100;MAX_SECTION_ATTEMPTS=50;ACCEPTABLE_PF=.05;FRACTION_TO_REPLACE=.2;JUMPER_PF_FN_ENABLED=!1;SHUFFLE_SEEDS_PER_SECTION=null;ALWAYS_RIP_INTERSECTIONS=!0;effort=1;HYPERPARAMETER_SCHEDULE=Lh;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.simpleRouteJson=t.simpleRouteJson,this.inputNodes=t.inputNodes,this.capacityMeshNodes=t.capacityMeshNodes,this.capacityMeshEdges=t.capacityMeshEdges,this.colorMap=t.colorMap??{},this.effort=t.effort??1,void 0!==t.FRACTION_TO_REPLACE&&(this.FRACTION_TO_REPLACE=t.FRACTION_TO_REPLACE),void 0!==t.ALWAYS_RIP_INTERSECTIONS&&(this.ALWAYS_RIP_INTERSECTIONS=t.ALWAYS_RIP_INTERSECTIONS),void 0!==t.MAX_ATTEMPTS_PER_NODE&&(this.MAX_ATTEMPTS_PER_NODE=t.MAX_ATTEMPTS_PER_NODE),void 0!==t.MAX_SECTION_ATTEMPTS&&(this.MAX_SECTION_ATTEMPTS=t.MAX_SECTION_ATTEMPTS),void 0!==t.HYPERPARAMETER_SCHEDULE&&(this.HYPERPARAMETER_SCHEDULE=t.HYPERPARAMETER_SCHEDULE),this.JUMPER_PF_FN_ENABLED=t.JUMPER_PF_FN_ENABLED??this.JUMPER_PF_FN_ENABLED,this.SHUFFLE_SEEDS_PER_SECTION=t.SHUFFLE_SEEDS_PER_SECTION,this.MAX_SECTION_ATTEMPTS*=this.effort,this.nodeMap=new Map(t.inputNodes.map(t=>[t.capacityMeshNodeId,t])),this.capacityMeshNodeMap=new Map(t.capacityMeshNodes.map(t=>[t.capacityMeshNodeId,t])),this.connectionResults=[...t.initialConnectionResults],this.assignedPortPoints=new Map(t.initialAssignedPortPoints),this.nodeAssignedPortPoints=new Map(t.initialNodeAssignedPortPoints),this.nodePfMap=this.computeInitialPfMap();const e=this.computeBoardScore();this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.nodesExamined=0,this.stats.sectionAttempts=0,this.stats.sectionScores={},this.stats.initialBoardScore=e,this.stats.currentBoardScore=e,this.stats.errors=0}computeInitialPfMap(){const t=new Map;for(const e of this.capacityMeshNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];if(0===n.length)continue;const s={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===e.availableZ.length?_h(e,xh(s).numSameLayerCrossings):Mh(s,e);t.set(e.capacityMeshNodeId,o)}return t}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.computeScoreForNodes(t)}computeScoreForNodes(t){return this.JUMPER_PF_FN_ENABLED?Oh(t,this.capacityMeshNodeMap):Sh(t,this.capacityMeshNodeMap)}recomputePfForNodes(t){for(const e of t){const t=this.capacityMeshNodeMap.get(e);if(!t)continue;const n=this.nodeAssignedPortPoints.get(e)??[];if(0===n.length){this.nodePfMap.set(e,0);continue}const s={capacityMeshNodeId:e,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?_h(t,xh(s).numSameLayerCrossings):Mh(s,t);this.nodePfMap.set(e,o)}}getCreatePortPointSectionInput(){return{inputNodes:this.inputNodes,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,nodeMap:this.nodeMap,connectionResults:this.connectionResults}}createSection(t){return function(t,e){const{inputNodes:n,capacityMeshNodes:s,capacityMeshEdges:o,connectionResults:i}=t,{centerOfSectionCapacityNodeId:r,expansionDegrees:a}=e,c=new Map;for(const t of o){const[e,n]=t.nodeIds;c.has(e)||c.set(e,new Set),c.has(n)||c.set(n,new Set),c.get(e).add(n),c.get(n).add(e)}const h=new Set,l=new Set,d=[];for(d.push({nodeId:r,depth:0}),l.add(r);d.length>0;){const{nodeId:t,depth:e}=d.shift();if(h.add(t),e<a){const n=c.get(t)??new Set;for(const t of n)l.has(t)||(l.add(t),d.push({nodeId:t,depth:e+1}))}}const u=n.filter(t=>h.has(t.capacityMeshNodeId)),p=s.filter(t=>h.has(t.capacityMeshNodeId)),f=[],m=[];for(const t of o){const[e,n]=t.nodeIds,s=h.has(e),o=h.has(n);s&&o?f.push(t):(s||o)&&m.push(t)}const g=u.map(t=>{const e=t.portPoints.filter(t=>{const[e,n]=t.connectionNodeIds,s=h.has(e),o=h.has(n);return s||o});return{...t,portPoints:e}}),y=function(t,e){const n=[];for(const s of t){if(!s.path||0===s.path.length)continue;const t=s.connection.name,o=s.connection.rootConnectionName,i=[];for(let t=0;t<s.path.length;t++){const n=s.path[t];e.has(n.currentNodeId)&&i.push(t)}if(0===i.length)continue;const r=i[0],a=i[i.length-1];let c=r,h=a;if(r>0){const t=s.path[0].currentNodeId;(s.nodeIds[0]===t||s.nodeIds[1]===t)&&(c=0)}if(a<s.path.length-1){const t=s.path.length-1,e=s.path[t].currentNodeId;(s.nodeIds[0]===e||s.nodeIds[1]===e)&&(h=t)}const l=s.path.slice(c,h+1),d=c>0,u=h<s.path.length-1;n.push({connectionName:t,rootConnectionName:o,points:l.map(t=>({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId,portPointId:t.portPoint?.portPointId})),originalStartIndex:c,originalEndIndex:h,hasEntryFromOutside:d,hasExitToOutside:u})}return n}(i??[],h);return{centerNodeId:r,expansionDegrees:a,nodeIds:h,inputNodes:g,capacityMeshNodes:p,internalEdges:f,boundaryEdges:m,sectionPaths:y}}(this.getCreatePortPointSectionInput(),t)}getSectionNodesWithPortPoints(t){const e=[];for(const n of t.nodeIds){const t=this.nodeMap.get(n),s=this.capacityMeshNodeMap.get(n);if(!t||!s)continue;const o=this.nodeAssignedPortPoints.get(n)??[];o.length>0&&e.push({capacityMeshNodeId:n,center:t.center,width:t.width,height:t.height,portPoints:o,availableZ:t.availableZ})}return e}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}findHighestPfNode(){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_ATTEMPTS_PER_NODE)**2>e&&(e=s,t=n)}return!t||e<this.ACCEPTABLE_PF?null:t}currentSectionCutPathInfo=new Map;currentSectionKeptPortPoints=new Map;currentSectionFixedRoutes=[];determineConnectionsToRip(t,e){const n=31337*this.sectionAttempts,s=Dh(n);if(this.FRACTION_TO_REPLACE>=1)return new Set(e);const o=function(t,e){const n=Dh(e),s=[...t];for(let t=s.length-1;t>0;t--){const e=Math.floor(n()*(t+1));[s[t],s[e]]=[s[e],s[t]]}return s}(e,n),i=Math.max(1,Math.ceil(o.length*this.FRACTION_TO_REPLACE)),r=new Set(o.slice(0,i));if(this.ALWAYS_RIP_INTERSECTIONS){const n=function(t){const{section:e,nodePfMap:n,capacityMeshNodeMap:s,nodeAssignedPortPoints:o,acceptablePf:i}=t,r=[];for(const t of e.nodeIds){if((n.get(t)??0)<=i)continue;const e=s.get(t);if(!e)continue;const a=o.get(t)??[];if(a.length<2)continue;const c=e.center.x-e.width/2,h=e.center.x+e.width/2,l=e.center.y-e.height/2,d=e.center.y+e.height/2,u=new Map;for(const t of a){const e=u.get(t.connectionName)??[];e.some(e=>e.x===t.x&&e.y===t.y&&e.z===t.z)||e.push({x:t.x,y:t.y,z:t.z}),u.set(t.connectionName,e)}const p=new Map;for(const[t,e]of u){if(e.length<2)continue;const n=e[0],s=e[1];if(n.z!==s.z)continue;const o=Nh(n,c,h,l,d),i=Nh(s,c,h,l,d),r=n.z,a=p.get(r)??[];a.push({connectionName:t,t1:o,t2:i}),p.set(r,a)}const f=1e-6;for(const[,t]of p){const e=t.map(t=>({connectionName:t.connectionName,a:Math.min(t.t1,t.t2),b:Math.max(t.t1,t.t2)}));for(let t=0;t<e.length;t++){const{connectionName:n,a:s,b:o}=e[t];for(let i=t+1;i<e.length;i++){const{connectionName:t,a:a,b:c}=e[i];Math.abs(s-a)<f||Math.abs(s-c)<f||Math.abs(o-a)<f||Math.abs(o-c)<f||(s<a&&a<o&&o<c||a<s&&s<c&&c<o)&&r.push([n,t])}}}}return r}({section:t,nodePfMap:this.nodePfMap,capacityMeshNodeMap:this.capacityMeshNodeMap,nodeAssignedPortPoints:this.nodeAssignedPortPoints,acceptablePf:this.ACCEPTABLE_PF});for(const[t,o]of n){if(r.has(t)||r.has(o))continue;const n=e.includes(t),i=e.includes(o);if(n&&i){const e=s()<.5;r.add(e?t:o)}else n?r.add(t):i&&r.add(o)}}return this.stats.lastRipCount=r.size,r}createSectionSimpleRouteJson(t){const e=[];this.currentSectionCutPathInfo.clear(),this.currentSectionKeptPortPoints.clear(),this.currentSectionFixedRoutes=[];const n=[],s=[];for(const e of this.connectionResults){if(!e.path||0===e.path.length)continue;const[o,i]=e.nodeIds,r=t.nodeIds.has(o),a=t.nodeIds.has(i);r&&a&&(s.push(e),n.push(e.connection.name))}const o=[];for(const e of t.sectionPaths){if(!e.hasEntryFromOutside&&!e.hasExitToOutside)continue;if(e.points.length<2)continue;const t=this.connectionResults.find(t=>t.connection.name===e.connectionName);t&&(o.push({sectionPath:e,originalResult:t}),n.includes(e.connectionName)||n.push(e.connectionName))}const i=this.determineConnectionsToRip(t,n);for(const t of s)i.has(t.connection.name)&&e.push(t.connection);for(const{sectionPath:t,originalResult:n}of o){if(!i.has(t.connectionName))continue;const s=`__cut__${t.connectionName}__${t.originalStartIndex}`;this.colorMap[s]=this.colorMap[t.connectionName];const o=t.points[0],r=t.points[t.points.length-1],a={name:s,rootConnectionName:t.rootConnectionName??t.connectionName,pointsToConnect:[{x:o.x,y:o.y,layers:[`layer${o.z+1}`]},{x:r.x,y:r.y,layers:[`layer${r.z+1}`]}]};e.push(a),this.currentSectionCutPathInfo.set(s,{sectionPath:t,originalConnectionResult:n})}const r=new Set(n.filter(t=>!i.has(t)));if(r.size>0){for(const e of t.nodeIds){const t=(this.nodeAssignedPortPoints.get(e)??[]).filter(t=>r.has(t.connectionName));t.length>0&&this.currentSectionKeptPortPoints.set(e,t)}for(const t of s)r.has(t.connection.name)&&this.currentSectionFixedRoutes.push(t);for(const{sectionPath:t,originalResult:e}of o)if(r.has(t.connectionName)){const n={connection:{name:t.connectionName,rootConnectionName:t.rootConnectionName,pointsToConnect:e.connection.pointsToConnect},path:t.points.map(t=>({prevCandidate:null,portPoint:null,currentNodeId:t.nodeId,point:{x:t.x,y:t.y},z:t.z,f:0,g:0,h:0,distanceTraveled:0})),portPoints:t.points.map(e=>({portPointId:e.portPointId,x:e.x,y:e.y,z:e.z,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName})),nodeIds:e.nodeIds,straightLineDistance:e.straightLineDistance};this.currentSectionFixedRoutes.push(n)}}return{...this.simpleRouteJson,connections:e}}prepareSectionInputNodesForCutPaths(t){const e=new Set;for(const[,t]of this.currentSectionCutPathInfo.entries()){const{sectionPath:n}=t;if(0===n.points.length)continue;const s=n.points[0].nodeId;e.add(s);const o=n.points[n.points.length-1].nodeId;e.add(o)}return t.inputNodes.map(t=>e.has(t.capacityMeshNodeId)?{...t,_containsTarget:!0}:t)}getHyperParametersForScheduleIndex(t,e){const n=this.HYPERPARAMETER_SCHEDULE[t];return{...n,SHUFFLE_SEED:(n.SHUFFLE_SEED??0)+17*e}}createSectionSolver(t){const e=this.createSectionSimpleRouteJson(t),n=this.prepareSectionInputNodesForCutPaths(t),s=fh(e,n);for(const[t,e]of this.currentSectionKeptPortPoints){const n=s.nodeAssignedPortPoints.get(t)??[];s.nodeAssignedPortPoints.set(t,[...n,...e])}return new zh({simpleRouteJson:e,inputNodes:n,capacityMeshNodes:t.capacityMeshNodes,colorMap:this.colorMap,nodeMemoryPfMap:this.nodePfMap,numShuffleSeeds:this.SHUFFLE_SEEDS_PER_SECTION??2*e.connections.length*this.effort,hyperParameters:{...this.getHyperParametersForScheduleIndex(this.currentScheduleIndex,this.sectionAttempts)},precomputedInitialParams:s,fixedRoutes:this.currentSectionFixedRoutes})}reattachSection(t,e,n,s){const o=[],i=[];for(const t of e)t.connection.name.startsWith("__cut__")?i.push(t):o.push(t);const r=new Set(o.map(t=>t.connection.name));this.connectionResults=this.connectionResults.filter(t=>!r.has(t.connection.name)),this.connectionResults.push(...o);for(const[e,n]of this.nodeAssignedPortPoints.entries()){if(!t.nodeIds.has(e))continue;const s=n.filter(t=>!r.has(t.connectionName));this.nodeAssignedPortPoints.set(e,s)}for(const[t,e]of this.assignedPortPoints.entries())r.has(e.connectionName)&&this.assignedPortPoints.delete(t);for(const e of i){const n=this.currentSectionCutPathInfo.get(e.connection.name);if(!n||!e.path)continue;const{sectionPath:s,originalConnectionResult:o}=n,i=o.path;if(!i)continue;const r=s.connectionName;for(const[e,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(n=>n.connectionName!==r||!t.nodeIds.has(e));this.nodeAssignedPortPoints.set(e,s)}const a=i.slice(0,s.originalStartIndex),c=i.slice(s.originalEndIndex+1),h=[];let l=a.length>0?a[a.length-1]:null;for(const t of e.path){const e={...t,prevCandidate:l};h.push(e),l=e}if(c.length>0&&h.length>0&&(c[0]={...c[0],prevCandidate:h[h.length-1]}),o.path=[...a,...h,...c],e.portPoints)for(const n of e.portPoints){const e={...n,connectionName:r,rootConnectionName:s.rootConnectionName??r};for(const s of t.inputNodes)for(const t of s.portPoints)if(Math.abs(t.x-n.x)<.001&&Math.abs(t.y-n.y)<.001&&t.z===n.z){for(const n of t.connectionNodeIds){const t=this.nodeAssignedPortPoints.get(n)??[];t.push(e),this.nodeAssignedPortPoints.set(n,t)}break}}}for(const[t,e]of n.entries())e.connectionName.startsWith("__cut__")||this.assignedPortPoints.set(t,e);for(const[t,e]of s.entries()){const n=e.filter(t=>!t.connectionName.startsWith("__cut__"));if(n.length>0){const e=this.nodeAssignedPortPoints.get(t)??[];this.nodeAssignedPortPoints.set(t,[...e,...n])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved||this.activeSubSolver.failed){if(this.activeSubSolver.failed){if(this.currentScheduleIndex++,this.activeSubSolver.error&&this.stats.errors++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0;return}const t=this.activeSubSolver.getNodesWithPortPoints().map(t=>({...t,portPoints:t.portPoints.map(t=>{if(t.connectionName.startsWith("__cut__")){const e=t.connectionName.slice(7),n=e.lastIndexOf("__"),s=n>=0?e.slice(0,n):e;return{...t,connectionName:s}}return t})})),e=new Set;for(const n of t)for(const t of n.portPoints)e.add(t.connectionName);const n=this.getSectionNodesWithPortPoints(this.currentSection).map(t=>({...t,portPoints:t.portPoints.filter(t=>e.has(t.connectionName))})).filter(t=>t.portPoints.length>0),s=this.computeScoreForNodes(n),o=this.computeScoreForNodes(t),i=`attempt${this.sectionAttempts}`;if(this.stats.lastSectionScore=o,o>s){const t=this.stats.currentBoardScore;this.stats.lastBoardScore=t;const e=[...this.connectionResults],n=new Map(this.assignedPortPoints),s=new Map(Array.from(this.nodeAssignedPortPoints.entries()).map(([t,e])=>[t,[...e]]));this.reattachSection(this.currentSection,this.activeSubSolver.connectionsWithResults,this.activeSubSolver.assignedPortPoints,this.activeSubSolver.nodeAssignedPortPoints),this.recomputePfForNodes(this.currentSection.nodeIds);const o=this.computeBoardScore();this.stats.sectionScores[i]=o,o>t?(this.stats.successfulOptimizations++,this.stats.currentBoardScore=o):(this.connectionResults=e,this.assignedPortPoints=n,this.nodeAssignedPortPoints=s,this.recomputePfForNodes(this.currentSection.nodeIds),this.stats.failedOptimizations++),this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}else if(this.currentScheduleIndex++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}return}if(this.sectionAttempts>=this.MAX_SECTION_ATTEMPTS)return void(this.solved=!0);const t=this.findHighestPfNode();if(!t)return void(this.solved=!0);this.sectionAttempts++,this.stats.sectionAttempts=this.sectionAttempts,this.stats.nodesExamined++,this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.currentSectionCenterNodeId=t,this.currentScheduleIndex=0;const e=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:t,expansionDegrees:e.EXPANSION_DEGREES});const n=this.getSectionNodesWithPortPoints(this.currentSection);this.sectionScoreBeforeOptimization=this.computeScoreForNodes(n);if(0===this.createSectionSimpleRouteJson(this.currentSection).connections.length)return this.currentSection=null,void(this.currentSectionCenterNodeId=null);this.activeSubSolver=this.createSectionSolver(this.currentSection)}computeProgress(){return this.sectionAttempts/this.MAX_SECTION_ATTEMPTS}visualize(){return this.solved?Rh(this):this.activeSubSolver?this.activeSubSolver.visualize():this.currentSection?function(t,e){const n={lines:[],points:[],rects:[],circles:[]};for(const e of t.inputNodes){const s=e.capacityMeshNodeId===t.centerNodeId,o=s?"rgba(0, 200, 0, 0.3)":"rgba(200, 200, 200, 0.3)";n.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,layer:`z${e.availableZ.join(",")}`,fill:o,label:`${e.capacityMeshNodeId}${s?" (CENTER)":""}`})}for(const e of t.inputNodes)for(const t of e.portPoints){const e="rgba(150, 150, 150, 0.5)";n.circles.push({center:{x:t.x,y:t.y},radius:.05,fill:e,layer:`z${t.z}`,label:[t.portPointId,`cd: ${t.distToCentermostPortOnZ}`,`connects: ${t.connectionNodeIds.join(",")}`].filter(Boolean).join("\n")})}for(const s of t.sectionPaths){const t=e?.[s.connectionName]??"blue";for(let e=0;e<s.points.length-1;e++){const o=s.points[e],i=s.points[e+1],r=o.z===i.z,a=o.z;let c;c=r?0===a?"5 5":"10 5":"3 3 10",n.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:t,strokeDash:c})}}return n}(this.currentSection,this.colorMap):Rh(this)}},Yh=class{parent={};constructor(t){for(const e of t)this.parent[e]=e}find(t){return this.parent[t]===t?t:this.parent[t]=this.find(this.parent[t])}union(t,e){const n=this.find(t),s=this.find(e);n!==s&&(this.parent[s]=n)}getGroup(t){const e=this.find(t),n=[];for(const t in this.parent)this.find(t)===e&&n.push(t);return n}},Xh=class{point;left=null;right=null;constructor(t){this.point=t}},kh=class{root=null;constructor(t){t.length>0&&(this.root=this.buildTree(t,0))}buildTree(t,e){const n=e%2==0?"x":"y";t.sort((t,e)=>t[n]-e[n]);const s=Math.floor(t.length/2),o=new Xh(t[s]);return s>0&&(o.left=this.buildTree(t.slice(0,s),e+1)),s<t.length-1&&(o.right=this.buildTree(t.slice(s+1),e+1)),o}findNearestNeighbor(t){if(!this.root)throw new Error("Tree is empty");const e=this.root.point,n=this.distance(t,e);return this.nearestNeighborSearch(this.root,t,0,e,n),e}nearestNeighborSearch(t,e,n,s,o){if(!t)return s;const i=n%2?"x":"y",r=this.distance(e,t.point);r<o&&(s=t.point,o=r);const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;return s=this.nearestNeighborSearch(c,e,n+1,s,o),o=this.distance(e,s),Math.abs(a)<o&&(s=this.nearestNeighborSearch(h,e,n+1,s,o)),s}findKNearestNeighbors(t,e){if(!this.root)return[];const n=[];return this.kNearestNeighborSearch(this.root,t,0,n,e),n.sort((t,e)=>t.distance-e.distance).slice(0,e).map(t=>t.point)}kNearestNeighborSearch(t,e,n,s,o){if(!t)return;const i=n%2?"x":"y",r=this.distance(e,t.point);s.push({point:t.point,distance:r});const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;this.kNearestNeighborSearch(c,e,n+1,s,o);let l=1/0;s.length>=o&&(s.sort((t,e)=>t.distance-e.distance),l=s[o-1]?.distance||1/0),(Math.abs(a)<l||s.length<o)&&this.kNearestNeighborSearch(h,e,n+1,s,o)}distance(t,e){return Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}},$h=class{parent=new Map;rank=new Map;constructor(t){for(const e of t){const t=this.pointToKey(e);this.parent.set(t,t),this.rank.set(t,0)}}pointToKey(t){return`${t.x},${t.y}`}find(t){const e=this.pointToKey(t);if(!this.parent.has(e))throw new Error(`Point ${e} not found in DisjointSet`);let n=e;for(;n!==this.parent.get(n);)n=this.parent.get(n);let s=e;for(;s!==n;){const t=this.parent.get(s);this.parent.set(s,n),s=t}return n}union(t,e){const n=this.find(t),s=this.find(e);if(n===s)return!1;const o=this.rank.get(n)||0,i=this.rank.get(s)||0;return o<i?this.parent.set(n,s):o>i?this.parent.set(s,n):(this.parent.set(s,n),this.rank.set(n,o+1)),!0}};function Bh(t){if(t.length<=1)return[];const e=[...t],n=new kh(e),s=[],o=Math.min(10,t.length-1);for(const t of e){const e=n.findKNearestNeighbors(t,o+1);for(const n of e){if(t.x===n.x&&t.y===n.y)continue;const e=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2);s.push({from:t,to:n,weight:e})}}s.sort((t,e)=>t.weight-e.weight);const i=new $h(e),r=[];for(const t of s)if(i.union(t.from,t.to)&&(r.push(t),r.length===e.length-1))break;return r}function jh(t){if(t.pointId)return t.pointId;let e="";var n;return"layer"in(n=t)&&"string"==typeof n.layer?e=t.layer:Cn(t)&&t.layers&&(e=t.layers.sort().join("-")),`${t.x.toFixed(4)},${t.y.toFixed(4)},${e}`}var Wh=class extends Ln{constructor(t,e={}){super(),this.ogSrj=t,this.colorMap=e,this.unprocessedConnections=function(t){if(0===t.length)return[];const e=t.map((t,e)=>`conn_${e}`),n=new Yh(e),s=new Map;t.forEach((t,e)=>{const n=`conn_${e}`;t.pointsToConnect.forEach(t=>{const e=jh(t);s.has(e)||s.set(e,[]),s.get(e).push(n)})});for(const t of s.values())if(t.length>1){const e=t[0];for(let s=1;s<t.length;s++)n.union(e,t[s])}const o=new Map;t.forEach((t,e)=>{const s=`conn_${e}`,i=n.find(s);o.has(i)||o.set(i,[]),o.get(i).push(t)});const i=[];for(const t of o.values()){if(1===t.length){i.push(t[0]);continue}const e=new Map,n=new Set;let s=!1;const o=[],r=new Set;let a;t.forEach(t=>{t.pointsToConnect.forEach(t=>e.set(jh(t),t)),n.add(t.name),t.isOffBoard&&(s=!0),t.externallyConnectedPointIds&&o.push(...t.externallyConnectedPointIds),t.netConnectionName&&r.add(t.netConnectionName),void 0===a&&void 0!==t.nominalTraceWidth&&(a=t.nominalTraceWidth)});const c={name:Array.from(n).join("__"),mergedConnectionNames:Array.from(n),pointsToConnect:Array.from(e.values()),isOffBoard:s,externallyConnectedPointIds:o.length>0?o:void 0,netConnectionName:r.size>0?Array.from(r).join("__"):void 0,nominalTraceWidth:a};i.push(c)}return i}([...t.connections]),this.newConnections=[]}getSolverName(){return"NetToPointPairsSolver"}unprocessedConnections;newConnections;_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;return void this.newConnections.push({...t,rootConnectionName:t.name})}const o=Bh(t.pointsToConnect);let i=0;for(const e of o)s(e.from,e.to)||this.newConnections.push({pointsToConnect:[e.from,e.to],name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}getNewSimpleRouteJson(){return{...structuredClone(this.ogSrj),connections:structuredClone(this.newConnections)}}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Net To Point Pairs Visualization"};return this.unprocessedConnections.forEach(e=>{e.pointsToConnect.forEach(n=>{t.points.push({x:n.x,y:n.y,color:"red",label:e.name})});const n=e.pointsToConnect.length**2,s=Un(0),o=new Set;for(let i=0;i<Math.max(n,2*e.pointsToConnect.length);i++){const n=Math.floor(s()*e.pointsToConnect.length),i=Math.floor(s()*e.pointsToConnect.length);o.has(`${n}-${i}`)||(o.add(`${n}-${i}`),t.lines.push({points:[e.pointsToConnect[n],e.pointsToConnect[i]],strokeColor:"rgba(255,0,0,0.25)"}))}}),this.newConnections.forEach(e=>{const n=this.colorMap?.[e.name]||"blue";e.pointsToConnect.forEach(s=>{t.points.push({x:s.x,y:s.y,color:n,label:e.name})});for(let s=0;s<e.pointsToConnect.length-1;s++)for(let o=s+1;o<e.pointsToConnect.length;o++)t.lines.push({points:[e.pointsToConnect[s],e.pointsToConnect[o]],strokeColor:n})}),t}},Hh=class extends Wh{constructor(t,e={}){const n=t.connections.flatMap(t=>t.pointsToConnect),s=new Map;for(const t of n)t.pointId&&s.set(t.pointId,t);const o=n.map(t=>t.pointId).filter(t=>!!t),i=new Yh(o),r=[];for(const e of t.connections)e.isOffBoard?e.pointsToConnect.length>=2&&e.pointsToConnect[0].pointId&&e.pointsToConnect[1].pointId&&i.union(e.pointsToConnect[0].pointId,e.pointsToConnect[1].pointId):r.push(e);super({...t,connections:r},e),this.ogSrj=t,this.colorMap=e,this.connectionPointDsu=i,this.connectionPointMap=s,this.ogSrj=t}getSolverName(){return"NetToPointPairsSolver2_OffBoardConnection"}connectionPointDsu;connectionPointMap;_findBestConnectionPointsFromDisjointSets(t,e){if(!t.pointId||!e.pointId)return{pointsToConnect:[t,e]};const n=this.connectionPointDsu.getGroup(t.pointId).map(t=>this.connectionPointMap.get(t)),s=this.connectionPointDsu.getGroup(e.pointId).map(t=>this.connectionPointMap.get(t));let o=t,i=e,r=1/0;for(const t of n)for(const e of s){const n=Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));n<r&&(r=n,o=t,i=e)}return{pointsToConnect:[o,i]}}_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;const e=this._findBestConnectionPointsFromDisjointSets(t.pointsToConnect[0],t.pointsToConnect[1]);return void this.newConnections.push({...t,pointsToConnect:e.pointsToConnect,rootConnectionName:t.name})}const o=Bh(t.pointsToConnect);let i=0;for(const e of o){if(s(e.from,e.to))continue;const n=this._findBestConnectionPointsFromDisjointSets(e.from,e.to);this.newConnections.push({pointsToConnect:n.pointsToConnect,name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}}},Uh=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){const t=this.netMap[n],s=this.netMap[e];if(t&&s){t.push(...s),this.netMap[e]=t;for(const e of t)this.idToNetMap[e]=n}}}for(const t of e){const e=this.netMap[n];e&&!e.includes(t)&&e.push(t),this.idToNetMap[t]=n}}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){if(0===t.length)return!0;const e=this.getNetConnectedToId(t[0]);if(!e)return!1;for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}};function Vh(t,e={}){const n=[],s=[],o=e.color??"gray",i=e.label,r=wn[t.footprint]??wn["0603"],a=t.end.x-t.start.x,c=t.end.y-t.start.y,h=Math.abs(a)>Math.abs(c),l=h?r.padLength:r.padWidth,d=h?r.padWidth:r.padLength;return n.push({center:t.start,width:l,height:d,fill:In(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (start)`:void 0}),n.push({center:t.end,width:l,height:d,fill:In(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (end)`:void 0}),s.push({points:[t.start,t.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"}),{rects:n,lines:s}}function Gh(t,e={}){const n={rects:[],lines:[]};for(const s of t){const{rects:t,lines:o}=Vh(s,e);n.rects.push(...t),n.lines.push(...o)}return n}var Zh=1e5,qh=.001,Jh=class extends Ln{getSolverName(){return"SingleHighDensityRouteStitchSolver"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;constructor(t){if(super(),this.remainingHdRoutes=[...t.hdRoutes],this.colorMap=t.colorMap??{},0===t.hdRoutes.length){this.start=t.start,this.end=t.end;const e=[{x:t.start.x,y:t.start.y,z:t.start.z}],n=[];return t.start.z!==t.end.z&&(e.push({x:t.start.x,y:t.start.y,z:t.end.z}),n.push({x:t.start.x,y:t.start.y})),e.push({x:t.end.x,y:t.end.y,z:t.end.z}),this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:t.hdRoutes[0]?.rootConnectionName,route:e,vias:n,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:t.defaultTraceThickness??.15},void(this.solved=!0)}let e=1/0,n=t.hdRoutes[0],s="start-to-end";for(const o of t.hdRoutes){const i=o.route[0],r=o.route[o.route.length-1],a=k(t.start,i),c=k(t.start,r),h=k(t.end,i),l=k(t.end,r),d=Math.min(a,c,h,l);d<e&&(e=d,n=o,s=Math.min(h,l)<Math.min(a,c)?"end-to-start":"start-to-end")}"start-to-end"===s?(this.start=t.start,this.end=t.end):(this.start=t.end,this.end=t.start);const o=n.route[0],i=n.route[n.route.length-1],r=k(this.start,o)<=k(this.start,i)?o:i;this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:n.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:r.z}],vias:[],jumpers:[],viaDiameter:n.viaDiameter,traceThickness:n.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=>!this.remainingHdRoutes.some(n=>{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=>t.z===e.z&&k(e,t)<.001)})))return{firstRoute:t}}return{firstRoute:this.remainingHdRoutes[0]}}_step(){if(0===this.remainingHdRoutes.length){const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];return this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z}),void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n="first",s=1/0;for(let o=0;o<this.remainingHdRoutes.length;o++){const i=this.remainingHdRoutes[o],r=i.route[0],a=i.route[i.route.length-1],c=k(t,r),h=k(t,a);let l=1/0;l=t.z===r.z?c<qh?c:Zh+c:c<qh?1e3+c:Zh+c,l<s&&(s=l,e=o,n="first");let d=1/0;d=t.z===a.z?h<qh?h:Zh+h:h<qh?1e3+h:Zh+h,d<s&&(s=d,e=o,n="last")}if(-1===e)return void(this.remainingHdRoutes=[]);const o=this.remainingHdRoutes[e];let i;this.remainingHdRoutes.splice(e,1),i="first"===n?o.route:[...o.route].reverse(),i.length>0&&k(t,i[0])<qh&&t.z===i[0].z?this.mergedHdRoute.route.push(...i.slice(1)):this.mergedHdRoute.route.push(...i),this.mergedHdRoute.vias.push(...o.vias),o.jumpers&&this.mergedHdRoute.jumpers.push(...o.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Single High Density Route Stitch Solver"};if(t.points?.push({x:this.start.x,y:this.start.y,color:"green",label:"Start"},{x:this.end.x,y:this.end.y,color:"red",label:"End"}),this.mergedHdRoute&&this.mergedHdRoute.route.length>1){t.lines?.push({points:this.mergedHdRoute.route.map(t=>({x:t.x,y:t.y})),strokeColor:"green"});for(const e of this.mergedHdRoute.route)t.points?.push({x:e.x,y:e.y,color:"green"});for(const e of this.mergedHdRoute.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:this.mergedHdRoute.viaDiameter/2,fill:"green"});if(this.mergedHdRoute.jumpers&&this.mergedHdRoute.jumpers.length>0){const e=Gh(this.mergedHdRoute.jumpers,{color:"green",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const[e,n]of this.remainingHdRoutes.entries()){const s=this.colorMap[n.connectionName]??"gray";n.route.length>1&&t.lines?.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:s});for(let o=0;o<n.route.length;o++){const i=n.route[o];t.points?.push({x:i.x+(e%2-.5)/500+(o%8-4)/1e3,y:i.y+(e%2-.5)/500+(o%8-4)/1e3,color:s,label:`Route ${n.connectionName} ${i===n.route[0]?"First":i===n.route[n.route.length-1]?"Last":""}`})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Gh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},Kh=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)},${Math.round(100*t.z)}`,Qh=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Uh({}),s=[],o=new Map;for(let e=0;e<t.hdRoutes.length;e++){const n=t.hdRoutes[e],o=n.route[0],i=n.route[n.route.length-1];s.push([`route_island_${e}`,`${n.connectionName}:${Kh(o)}`,`${n.connectionName}:${Kh(i)}`])}n.addConnections(s);for(const t of s)for(const e of t.slice(1))o.set(e,(o.get(e)??0)+1);this.unsolvedRoutes=[];const i=Array.from(new Set(Object.values(n.idToNetMap)));for(const e of i){const s=n.getIdsConnectedToNet(e),i=t.hdRoutes.filter((t,e)=>s.includes(`route_island_${e}`));if(0===i.length)continue;const r=t.connections.find(t=>t.name===i[0].connectionName),a=i.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),c=[];for(const t of a){const e=`${i[0].connectionName}:${Kh(t)}`;1===o.get(e)&&c.push(t)}if(0===c.length){console.log("no possible endpoints, can't stitch");continue}let h,l;2!==c.length?(h={...r.pointsToConnect[0],z:Rn(Tn(r.pointsToConnect[0]),t.layerCount)},l={...r.pointsToConnect[1],z:Rn(Tn(r.pointsToConnect[1]),t.layerCount)}):(h=c[0],l=c[1],k(h,r.pointsToConnect[1])<k(l,r.pointsToConnect[0])&&([h,l]=[l,h])),this.unsolvedRoutes.push({connectionName:i[0].connectionName,hdRoutes:i,start:h,end:l})}this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof Jh&&this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute),this.activeSolver=null):this.activeSolver.failed&&(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new Jh({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length&&t.points?.push(...e.points),e.lines?.length&&t.lines?.push(...e.lines),e.circles?.length&&t.circles?.push(...e.circles),e.rects?.length&&(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?In(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?In(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Gh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start (z=${e.start.z})`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End (z=${e.end.z})`}),t.lines?.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:n,strokeDash:"2 2"});for(const s of e.hdRoutes){s.route.length>1&&t.lines?.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:In(n,.5),strokeDash:"10 5"});for(const e of s.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:s.viaDiameter/2,fill:n});if(s.jumpers&&s.jumpers.length>0){const e=Gh(s.jumpers,{color:n,label:s.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},tl=class{tree;constructor(t=9){this.tree=new ot(t)}insert(t,e,n,s,o){this.tree.insert({minX:e,minY:n,maxX:s,maxY:o,data:t})}bulkLoad(t){const e=t.map(({item:t,minX:e,minY:n,maxX:s,maxY:o})=>({minX:e,minY:n,maxX:s,maxY:o,data:t}));this.tree.load(e)}search(t,e,n,s){return this.tree.search({minX:t,minY:e,maxX:n,maxY:s}).map(t=>t.data)}clear(){this.tree.clear()}},el=class{index;items=[];currentIndex=0;capacity;constructor(t){this.capacity=Math.max(1,t),this.index=new E(this.capacity)}insert(t,e,n,s,o){if(this.currentIndex>=this.index.numItems)throw new Error("Exceeded initial capacity");this.items[this.currentIndex]=t,this.index.add(e,n,s,o),this.currentIndex++}finish(){this.index.finish()}search(t,e,n,s){return this.index.search(t,e,n,s).map(t=>this.items[t]||null).filter(Boolean)}clear(){this.items=[],this.currentIndex=0,this.index=new E(this.capacity)}},nl=class{idx;storage=[];constructor(t="native",e=[]){"flatbush"===t?0===e.length?(this.idx=new tl,t="rbush"):this.idx=new el(e.length):this.idx="rbush"===t?new tl:new class{shi=new sl(e);insert(t){}search(t,e,n,s){const o=(t+n)/2,i=(e+s)/2,r=n-t,a=s-e;return this.shi.getNodesInArea(o,i,r,a)}clear(){}},e.forEach(t=>this.insert(t)),"flatbush"===t&&e.length>0&&this.idx.finish?.()}insert(t){this.storage.push(t),this.idx.insert(t,t.center.x-t.width/2,t.center.y-t.height/2,t.center.x+t.width/2,t.center.y+t.height/2)}search(t){return this.idx.search(t.minX,t.minY,t.maxX,t.maxY)}searchArea(t,e,n,s){return this.search({minX:t-n/2,minY:e-s/2,maxX:t+n/2,maxY:e+s/2})}},sl=class{constructor(t){this.obstacles=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=n.center.x-n.width/2,o=n.center.y-n.height/2,i=n.center.x+n.width/2,r=n.center.y+n.height/2;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},ol=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)});function il(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function rl(t,e,n){const s=il(e,n);if(0===s)return il(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return il(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function al(t,e,n,s){if(L(t,e,n,s))return 0;const o={x:t.x,y:t.y},i={x:e.x,y:e.y},r={x:n.x,y:n.y},a={x:s.x,y:s.y};return Math.min(rl(o,r,a),rl(i,r,a),rl(r,o,i),rl(a,o,i))}var cl=class{segmentBuckets;viaBuckets;CELL_SIZE;constructor(t,e=1){this.segmentBuckets=new Map,this.viaBuckets=new Map,this.CELL_SIZE=e;for(const e of t)if(e&&e.connectionName){if(e.route&&e.route.length>=2)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],s=e.route[t+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=ol(o),r={segmentId:`${e.connectionName}-seg-${t}`,segment:o,parentRoute:e},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(e.vias&&e.vias.length>0)for(let t=0;t<e.vias.length;t++){const n=e.vias[t];if(null==n)continue;const s={viaId:`${e.connectionName}-via-${t}`,x:n.x,y:n.y,parentRoute:e},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}else console.warn("Skipping route with missing data:",e)}getConflictingRoutesForSegment(t,e,n){const s=ol([t,e]),o=s.minX-n,i=s.minY-n,r=s.maxX+n,a=s.maxY+n,c=Math.floor(o/this.CELL_SIZE),h=Math.floor((r+1e-9)/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor((a+1e-9)/this.CELL_SIZE),u=new Map,p=new Set,f=new Set,m={x:t.x,y:t.y},g={x:e.x,y:e.y};for(let s=c;s<=h;s++)for(let o=l;o<=d;o++){const i=`${s}x${o}`,r=this.segmentBuckets.get(i);if(r)for(const s of r){if(p.has(s.segmentId))continue;p.add(s.segmentId);const o=s.parentRoute,[i,r]=s.segment,a=n+o.traceThickness/2,c=a*a,h=al(t,e,i,r);if(h<c){const t=o.connectionName,e=u.get(t);(!e||h<e.minDistSq)&&u.set(t,{route:o,minDistSq:h})}}const a=this.viaBuckets.get(i);if(a)for(const t of a){if(f.has(t.viaId))continue;f.add(t.viaId);const e=t.parentRoute,s={x:t.x,y:t.y},o=n+e.viaDiameter/2,i=o*o,r=rl(s,m,g);if(r<i){const t=e.connectionName,n=u.get(t);(!n||r<n.minDistSq)&&u.set(t,{route:e,minDistSq:r})}}}const y=[];for(const t of u.values())y.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return y}removeRoute(t){for(const[e,n]of this.segmentBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.segmentBuckets.delete(e):s.length!==n.length&&this.segmentBuckets.set(e,s)}for(const[e,n]of this.viaBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.viaBuckets.delete(e):s.length!==n.length&&this.viaBuckets.set(e,s)}}addRoute(t){if(!t||!t.connectionName)return void console.warn("Skipping route with missing data:",t);if(t.route&&t.route.length>=2)for(let e=0;e<t.route.length-1;e++){const n=t.route[e],s=t.route[e+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=ol(o),r={segmentId:`${t.connectionName}-seg-${e}`,segment:o,parentRoute:t},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(t.vias&&t.vias.length>0)for(let e=0;e<t.vias.length;e++){const n=t.vias[e];if(null==n)continue;const s={viaId:`${t.connectionName}-via-${e}`,x:n.x,y:n.y,parentRoute:t},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}getConflictingRoutesNearPoint(t,e){const n=t.x-e,s=t.y-e,o=t.x+e,i=t.y+e,r=Math.floor(n/this.CELL_SIZE),a=Math.floor((o+1e-9)/this.CELL_SIZE),c=Math.floor(s/this.CELL_SIZE),h=Math.floor((i+1e-9)/this.CELL_SIZE),l=new Map,d=new Set,u=new Set;for(let n=r;n<=a;n++)for(let s=c;s<=h;s++){const o=`${n}x${s}`,i=this.segmentBuckets.get(o);if(i)for(const n of i){if(d.has(n.segmentId))continue;d.add(n.segmentId);const s=n.segment[0],o=n.segment[1];if(s.z!==o.z||s.z!==t.z)continue;const i=n.parentRoute,r={x:n.segment[0].x,y:n.segment[0].y},a={x:n.segment[1].x,y:n.segment[1].y},c=e+i.traceThickness/2,h=c*c,u=rl(t,r,a);if(u<h){const t=i.connectionName,e=l.get(t);(!e||u<e.minDistSq)&&l.set(t,{route:i,minDistSq:u})}}const r=this.viaBuckets.get(o);if(r)for(const n of r){if(u.has(n.viaId))continue;u.add(n.viaId);const s=n.parentRoute,o={x:n.x,y:n.y},i=e+s.viaDiameter/2,r=i*i,a=il(t,o);if(a<r){const t=s.connectionName,e=l.get(t);(!e||a<e.minDistSq)&&l.set(t,{route:s,minDistSq:a})}}}const p=[];for(const t of l.values())p.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return p}},hl=class extends Ln{getSolverName(){return"SingleRouteUselessViaRemovalSolver"}obstacleSHI;hdRouteSHI;unsimplifiedRoute;routeSections;currentSectionIndex;TRACE_THICKNESS=.15;OBSTACLE_MARGIN=.1;constructor(t){super(),this.currentSectionIndex=0,this.obstacleSHI=t.obstacleSHI,this.hdRouteSHI=t.hdRouteSHI,this.unsimplifiedRoute=t.unsimplifiedRoute,this.routeSections=this.breakRouteIntoSections(this.unsimplifiedRoute)}breakRouteIntoSections(t){const e=[],n=t.route;if(0===n.length)return[];let s={startIndex:0,endIndex:-1,z:n[0].z,points:[n[0]]};for(let t=1;t<n.length;t++)n[t].z===s.z?s.points.push(n[t]):(s.endIndex=t-1,e.push(s),s={startIndex:t,endIndex:-1,z:n[t].z,points:[n[t]]});return s.endIndex=n.length-1,e.push(s),e}_step(){if(this.currentSectionIndex>=this.routeSections.length)return void(this.solved=!0);if(0===this.currentSectionIndex&&this.routeSections.length>1){const t=this.routeSections[0],e=this.routeSections[1];if(t.z!==e.z){const n=e.z,s=t.points[0];if(this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n}))return t.z=n,t.points=t.points.map(t=>({...t,z:n})),void(this.currentSectionIndex=2)}return void this.currentSectionIndex++}if(this.currentSectionIndex===this.routeSections.length-1){if(this.routeSections.length>=2){const t=this.routeSections[this.routeSections.length-1],e=this.routeSections[this.routeSections.length-2];if(t.z!==e.z){const n=e.z,s=t.points[t.points.length-1];this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n})&&(t.z=n,t.points=t.points.map(t=>({...t,z:n})))}}return void(this.solved=!0)}const t=this.routeSections[this.currentSectionIndex-1],e=this.routeSections[this.currentSectionIndex],n=this.routeSections[this.currentSectionIndex+1];if(t.z!==n.z)return void this.currentSectionIndex++;const s=t.z;if(this.canSectionMoveToLayer({currentSection:e,targetZ:s}))return e.z=s,e.points=e.points.map(t=>({...t,z:s})),void(this.currentSectionIndex+=2);this.currentSectionIndex++}canEndpointConnectOnLayer(t,e,n){const s=this.obstacleSHI.searchArea(t,e,2,2).filter(n=>{if(!n.connectedTo?.includes(this.unsimplifiedRoute.connectionName))return!1;const s=n.width/2+.05,o=n.height/2+.05,i=Math.abs(t-n.center.x)<=s,r=Math.abs(e-n.center.y)<=o;return i&&r});return!(s.length>0)||s.some(t=>t.zLayers?.includes(n))}canSectionMoveToLayer({currentSection:t,targetZ:e}){for(let n=0;n<t.points.length-1;n++){const s={...t.points[n],z:e},o={...t.points[n+1],z:e},i=this.hdRouteSHI.getConflictingRoutesForSegment(s,o,this.TRACE_THICKNESS);for(const{conflictingRoute:t,distance:e}of i)if(t.connectionName!==this.unsimplifiedRoute.connectionName&&e<this.TRACE_THICKNESS+t.traceThickness)return!1;const r={centerX:(s.x+o.x)/2,centerY:(s.y+o.y)/2,width:Math.abs(s.x-o.x),height:Math.abs(s.y-o.y)},a=this.obstacleSHI.searchArea(r.centerX,r.centerY,r.width+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN),r.height+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN));for(const t of a){if(t.connectedTo?.includes(this.unsimplifiedRoute.connectionName))continue;if(t.zLayers?.includes(e)){if(Math.abs(s.x-t.center.x)<.01&&Math.abs(s.y-t.center.y)<.01||Math.abs(o.x-t.center.x)<.01&&Math.abs(o.y-t.center.y)<.01)continue}if(Q(s,o,t)<this.TRACE_THICKNESS+this.OBSTACLE_MARGIN)return!1}}return!0}getConstructorParams(){return{obstacleSHI:this.obstacleSHI,hdRouteSHI:this.hdRouteSHI,unsimplifiedRoute:this.unsimplifiedRoute}}getOptimizedHdRoute(){const t=this.routeSections.flatMap(t=>t.points),e=[];for(let n=0;n<t.length-1;n++)t[n].z!==t[n+1].z&&e.push({x:t[n].x,y:t[n].y});return{connectionName:this.unsimplifiedRoute.connectionName,rootConnectionName:this.unsimplifiedRoute.rootConnectionName,route:t,traceThickness:this.unsimplifiedRoute.traceThickness,vias:e,viaDiameter:this.unsimplifiedRoute.viaDiameter,jumpers:this.unsimplifiedRoute.jumpers}}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Route Useless Via Removal Solver"};for(let e=0;e<this.routeSections.length;e++){const n=this.routeSections[e];t.lines.push({points:n.points,strokeWidth:this.TRACE_THICKNESS,strokeColor:e===this.currentSectionIndex?"orange":0===n.z?"red":"blue"})}return t}},ll=(t,e=2)=>{const n=Array.from({length:e},(t,e)=>e);return t.map(t=>{const s=t.zLayers??t.layers?.map(t=>Rn(t,e))??n,o=Array.from(new Set(s.filter(t=>t>=0&&t<e)));return{...t,zLayers:o.length>0?o:n}})},dl=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:ll(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.optimizedHdRoutes=[],this.unprocessedRoutes=[...t.unsimplifiedHdRoutes],this.obstacleSHI=new nl("flatbush",this.input.obstacles),this.hdRouteSHI=new cl(this.unsimplifiedHdRoutes)}getSolverName(){return"UselessViaRemovalSolver"}unsimplifiedHdRoutes;optimizedHdRoutes;unprocessedRoutes;activeSubSolver=null;obstacleSHI=null;hdRouteSHI=null;_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.optimizedHdRoutes.push(this.activeSubSolver.getOptimizedHdRoute()),this.activeSubSolver=null):(this.activeSubSolver.failed||this.activeSubSolver.error)&&(this.error=this.activeSubSolver.error,this.failed=!0));const t=this.unprocessedRoutes.shift();t?this.activeSubSolver=new hl({hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,unsimplifiedRoute:t}):this.solved=!0}getOptimizedHdRoutes(){return this.optimizedHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Useless Via Removal Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.optimizedHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Gh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},ul=class extends Ln{getSolverName(){return"SingleSimplifiedPathSolver"}newRoute;newVias;headIndex=0;tailIndex=0;inputRoute;otherHdRoutes;obstacles;connMap;colorMap;outline;constructor(t){super(),this.inputRoute=t.inputRoute,this.otherHdRoutes=t.otherHdRoutes,this.obstacles=t.obstacles,this.connMap=t.connMap,this.colorMap=t.colorMap,this.outline=t.outline,this.newRoute=[this.inputRoute.route[0]],this.newVias=[]}getConstructorParams(){return{inputRoute:this.inputRoute,otherHdRoutes:this.otherHdRoutes,obstacles:this.obstacles,connMap:this.connMap.netMap,colorMap:this.colorMap,outline:this.outline}}get simplifiedRoute(){return{connectionName:this.inputRoute.connectionName,rootConnectionName:this.inputRoute.rootConnectionName,traceThickness:this.inputRoute.traceThickness,viaDiameter:this.inputRoute.viaDiameter,route:this.newRoute,vias:this.newVias,jumpers:this.inputRoute.jumpers}}isValidPath(t){throw new Error("Not implemented")}_step(){throw new Error("Not implemented")}getVisualsForNewRouteAndObstacles(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Simplified Path Solver"};for(let e=0;e<this.inputRoute.route.length-1;e++)t.lines.push({points:[{x:this.inputRoute.route[e].x,y:this.inputRoute.route[e].y},{x:this.inputRoute.route[e+1].x,y:this.inputRoute.route[e+1].y}],strokeColor:"rgba(255, 0, 0, 0.8)",strokeDash:1===this.inputRoute.route[e].z?"5, 5":void 0,layer:`z${this.inputRoute.route[e].z.toString()}`});for(let e=0;e<this.newRoute.length;e++)e<this.newRoute.length-1&&t.lines.push({points:[{x:this.newRoute[e].x,y:this.newRoute[e].y},{x:this.newRoute[e+1].x,y:this.newRoute[e+1].y}],strokeWidth:.15,strokeColor:"rgba(0, 255, 0, 0.8)",strokeDash:1===this.newRoute[e].z?[.4,.4]:void 0,layer:`z${this.newRoute[e].z.toString()}`}),t.points.push({x:this.newRoute[e].x,y:this.newRoute[e].y,color:"rgba(0, 255, 0, 0.8)",label:`z: ${this.newRoute[e].z}`,layer:`z${this.newRoute[e].z.toString()}`});for(const e of this.newVias)t.circles.push({center:e,radius:this.inputRoute.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)"});for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});for(const e of this.otherHdRoutes)for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:0===e.route[n].z?"rgba(255, 0, 255, 0.5)":1===e.route[n].z?"rgba(128, 0, 128, 0.5)":"rgba(0, 0, 255, 0.5)",layer:`z${e.route[n].z.toString()}`});if("filteredObstaclePathSegments"in this){const e=this.filteredObstaclePathSegments;for(const[n,s]of e)t.lines.push({points:[n,s]})}return t}};function pl(t,e,n,s){if(L(t,e,n,s))return 0;const o=fl(t,n,s),i=fl(e,n,s),r=fl(n,t,e),a=fl(s,t,e);return Math.min(o,i,r,a)}function fl(t,e,n){const s={x:n.x-e.x,y:n.y-e.y},o=ml({x:t.x-e.x,y:t.y-e.y},s);if(o<=0)return gl(t,e);const i=ml(s,s);if(i<=o)return gl(t,n);const r=o/i;return gl(t,{x:e.x+r*s.x,y:e.y+r*s.y})}function ml(t,e){return t.x*e.x+t.y*e.y}function gl(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var yl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)}),xl=class{constructor(t){this.segments=t,this.buckets=new Map;const e=new Map;for(const n of t){const t=this.getSegmentKey(n);if(e.has(t))continue;e.set(t,n);const s=yl(n),o=Math.floor(s.minX/this.CELL_SIZE),i=Math.floor(s.maxX/this.CELL_SIZE),r=Math.floor(s.minY/this.CELL_SIZE),a=Math.floor(s.maxY/this.CELL_SIZE);for(let e=o;e<=i;e++)for(let s=r;s<=a;s++){const o=`${e}x${s}`,i=this.buckets.get(o),r=[n[0],n[1],t];i?i.push(r):this.buckets.set(o,[r])}}}buckets;CELL_SIZE=.4;SEGMENT_MARGIN=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getSegmentKey(t){return`${t[0].x}-${t[0].y}-${t[0].z}-${t[1].x}-${t[1].y}-${t[1].z}`}getSegmentsThatCouldIntersect(t,e){const n=[],s=new Set,o=Math.min(t.x,e.x)-this.SEGMENT_MARGIN,i=Math.min(t.y,e.y)-this.SEGMENT_MARGIN,r=Math.max(t.x,e.x)+this.SEGMENT_MARGIN,a=Math.max(t.y,e.y)+this.SEGMENT_MARGIN,c=Math.floor(o/this.CELL_SIZE),h=Math.floor(r/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor(a/this.CELL_SIZE);for(let t=c;t<=h;t++)for(let e=l;e<=d;e++){const o=`${t}x${e}`,i=this.buckets.get(o);if(i)for(const t of i){const e=t[2];s.has(e)||(s.add(e),n.push(t))}}return n}},vl=1e-6,bl=(t,e,n)=>X(t,e,n)<=vl,Pl=(t,e)=>Math.abs(t.x-e.x)<=vl&&Math.abs(t.y-e.y)<=vl,Sl=(t,e)=>{if(!e||e.length<3)return!1;for(let n=0;n<e.length;n++){const s=e[n],o=e[(n+1)%e.length];if(bl(t,s,o))return!0}let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s],r=e[o];i.y>t.y!=r.y>t.y&&t.x<(r.x-i.x)*(t.y-i.y)/(r.y-i.y)+i.x&&(n=!n)}return n},Ml=class extends ul{pathSegments=[];totalPathLength=0;headDistanceAlongPath=0;tailDistanceAlongPath=0;minStepSize=.25;lastValidPath=null;lastValidPathHeadDistance=0;STEP_SIZE_REDUCTION_FACTOR=.25;maxStepSize=4;currentStepSize=this.maxStepSize;lastHeadMoveDistance=0;cachedValidPathSegments;filteredObstacles=[];filteredObstaclePathSegments=[];filteredVias=[];filteredJumperPads=[];jumperPadPointIndices=new Set;segmentTree;OBSTACLE_MARGIN=.1;TRACE_THICKNESS=.15;TAIL_JUMP_RATIO=.8;constructor(t){if(super(t),this.cachedValidPathSegments=new Set,this.inputRoute.route.length<=1)return this.newRoute=[...this.inputRoute.route],void(this.solved=!0);const e=this.inputRoute.route.reduce((t,e)=>(t.minX=Math.min(t.minX,e.x),t.maxX=Math.max(t.maxX,e.x),t.minY=Math.min(t.minY,e.y),t.maxY=Math.max(t.maxY,e.y),t),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0}),n={center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY};this.filteredObstacles=this.obstacles.filter(t=>!t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t))).filter(t=>{if(t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t)))return!1;return function(t,e){const n=z(t),s=z(e),o=Math.max(n.minX-s.maxX,s.minX-n.maxX,0),i=Math.max(n.minY-s.maxY,s.minY-n.maxY,0);return Math.hypot(o,i)}(n,t)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2}),this.filteredObstaclePathSegments=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.route,s=[];for(let t=0;t<n.length-1;t++){const o=n[t],i=n[t+1],r=Math.min(o.x,i.x),a=Math.max(o.x,i.x),c=Math.min(o.y,i.y),h=Math.max(o.y,i.y);r<=e.maxX&&a>=e.minX&&c<=e.maxY&&h>=e.minY&&s.push([o,i])}return s}),this.segmentTree=new xl(this.filteredObstaclePathSegments),this.filteredVias=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.vias,s=[];for(const o of n){const n=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2+t.viaDiameter/2,i=o.x-n,r=o.x+n,a=o.y-n,c=o.y+n;i<=e.maxX&&r>=e.minX&&a<=e.maxY&&c>=e.minY&&s.push({...o,diameter:t.viaDiameter})}return s});const s=(t,n)=>{const s=[];for(const o of t){const t=wn[o.footprint]??wn["0603"],i=o.end.x-o.start.x,r=o.end.y-o.start.y,a=Math.abs(i)>Math.abs(r),c=a?t.padLength:t.padWidth,h=a?t.padWidth:t.padLength,l=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2;o.start.x-c/2-l<=e.maxX&&o.start.x+c/2+l>=e.minX&&o.start.y-h/2-l<=e.maxY&&o.start.y+h/2+l>=e.minY&&s.push({center:o.start,width:c,height:h,connectionName:n}),o.end.x-c/2-l<=e.maxX&&o.end.x+c/2+l>=e.minX&&o.end.y-h/2-l<=e.maxY&&o.end.y+h/2+l>=e.minY&&s.push({center:o.end,width:c,height:h,connectionName:n})}return s};if(this.filteredJumperPads=this.otherHdRoutes.flatMap(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName)?[]:s(t.jumpers??[],t.connectionName)),this.inputRoute.jumpers&&this.inputRoute.jumpers.length>0){this.filteredJumperPads.push(...s(this.inputRoute.jumpers,this.inputRoute.connectionName));for(const t of this.inputRoute.jumpers)for(let e=0;e<this.inputRoute.route.length;e++){const n=this.inputRoute.route[e];(Math.abs(n.x-t.start.x)<.01&&Math.abs(n.y-t.start.y)<.01||Math.abs(n.x-t.end.x)<.01&&Math.abs(n.y-t.end.y)<.01)&&this.jumperPadPointIndices.add(e)}}this.computePathSegments()}computePathSegments(){let t=0;for(let e=0;e<this.inputRoute.route.length-1;e++){const n=this.inputRoute.route[e],s=this.inputRoute.route[e+1],o=Math.sqrt((s.x-n.x)**2+(s.y-n.y)**2)+e/1e4;this.pathSegments.push({start:n,end:s,length:o,startDistance:t,endDistance:t+o}),t+=o}this.totalPathLength=t}arePointsEqual(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z}getPointAtDistance(t){t=Math.max(0,Math.min(t,this.totalPathLength));const e=this.pathSegments.find(e=>t>=e.startDistance&&t<=e.endDistance);if(!e)return this.inputRoute.route[this.inputRoute.route.length-1];const n=(t-e.startDistance)/e.length;return{x:e.start.x+n*(e.end.x-e.start.x),y:e.start.y+n*(e.end.y-e.start.y),z:n<.5?e.start.z:e.end.z}}getNearestIndexForDistance(t){if(t<=0)return 0;if(t>=this.totalPathLength)return this.inputRoute.route.length-1;const e=this.pathSegments.findIndex(e=>t>=e.startDistance&&t<=e.endDistance);if(-1===e)return 0;const n=this.pathSegments[e],s=(n.startDistance+n.endDistance)/2;return t>s?e+1:e}isValidPathSegment(t,e){for(const n of this.filteredObstacles){if(!n.zLayers?.includes(t.z))continue;if(Q(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}const n=this.segmentTree.getSegmentsThatCouldIntersect(t,e);for(const[s,o,i]of n)if(s.z===t.z&&o.z===t.z){if(pl({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:o.x,y:o.y})<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS)return!1}for(const n of this.filteredVias)if(X(n,t,e)<this.OBSTACLE_MARGIN+n.diameter/2+this.TRACE_THICKNESS/2)return!1;for(const n of this.filteredJumperPads){if(Q(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}if(this.outline&&this.outline.length>=3){const n=(({start:t,end:e,polygon:n,margin:s=.2})=>{if(!n||n.length<3)return!1;const o=Sl(t,n),i=Sl(e,n);if(!o||!i)return!0;for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length],a=bl(t,i,r),c=bl(e,i,r);if(a&&c)continue;if(!L(t,e,i,r)){if(!a&&!c&&pl(t,e,i,r)<s-vl)return!0;continue}const h=$(t,e,i,r);if(!(h&&(a&&Pl(h,t)||c&&Pl(h,e))||h&&(Pl(h,t)||Pl(h,e))))return!0}return!1})({start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},polygon:this.outline});if(n)return!1}return!0}isValidPath(t){if(t.length<2)return!0;for(let e=0;e<t.length-1;e++)if(t[e].z!==t[e+1].z)return!1;for(let e=0;e<t.length-1;e++)if(!this.isValidPathSegment(t[e],t[e+1]))return!1;return!0}find45DegreePath(t,e){if(this.arePointsEqual(t,e))return[t];if(t.z!==e.z)return null;const n=((t,e)=>{const n=[],s=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x>t.x?1:-1,r=e.y>t.y?1:-1,a={x:e.x-i*Math.abs(e.y-t.y),y:t.y};(a.x-t.x)*i>=0&&(a.x-e.x)*i<=0&&n.push([t,a,e]);const c={x:t.x,y:e.y-r*Math.abs(e.x-t.x)};(c.y-t.y)*r>=0&&(c.y-e.y)*r<=0&&n.push([t,c,e]);const h=Math.min(s,o),l={x:t.x+i*h,y:t.y+r*h};return(l.x-t.x)*i>=0&&(l.x-e.x)*i<=0&&(l.y-t.y)*r>=0&&(l.y-e.y)*r<=0&&n.push([t,l,e]),n})({x:t.x,y:t.y},{x:e.x,y:e.y});for(const e of n){const n=e.map(e=>({x:e.x,y:e.y,z:t.z}));if(this.isValidPath(n))return n}return null}addPathToResult(t){if(0!==t.length){for(let e=0;e<t.length;e++)0===e&&this.newRoute.length>0&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t[e])||this.newRoute.push(t[e]);this.currentStepSize=this.maxStepSize}}moveHead(t){this.lastHeadMoveDistance=t,this.headDistanceAlongPath=Math.min(this.headDistanceAlongPath+t,this.totalPathLength)}stepBackAndReduceStepSize(){this.headDistanceAlongPath=Math.max(this.tailDistanceAlongPath,this.headDistanceAlongPath-this.lastHeadMoveDistance),this.currentStepSize=Math.max(this.minStepSize,this.currentStepSize*this.STEP_SIZE_REDUCTION_FACTOR)}_step(){const t=this.tailDistanceAlongPath>=this.totalPathLength,e=this.headDistanceAlongPath>=this.totalPathLength;if(t){const t=this.inputRoute.route[this.inputRoute.route.length-1];return 0!==this.newRoute.length&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t)||this.newRoute.push(t),void(this.solved=!0)}if(e){const t=this.getPointAtDistance(this.tailDistanceAlongPath),e=this.inputRoute.route[this.inputRoute.route.length-1],n=this.find45DegreePath(t,e);if(n)return this.addPathToResult(n),void(this.solved=!0);this.lastValidPath=null,this.tailDistanceAlongPath=this.totalPathLength,this.headDistanceAlongPath=this.totalPathLength;const s=[];for(const t of this.inputRoute.route)0!==s.length&&this.arePointsEqual(s[s.length-1],t)||s.push(t);return this.newRoute=s,this.newVias=[...this.inputRoute.vias],void(this.solved=!0)}this.moveHead(this.currentStepSize);const n=this.getPointAtDistance(this.tailDistanceAlongPath),s=this.getPointAtDistance(this.headDistanceAlongPath),o=this.getNearestIndexForDistance(this.tailDistanceAlongPath),i=this.getNearestIndexForDistance(this.headDistanceAlongPath);let r=!1,a=-1;for(let t=o;t<i;t++)if(t+1<this.inputRoute.route.length&&this.inputRoute.route[t].z!==this.inputRoute.route[t+1].z){r=!0;const e=t;a=this.pathSegments[e].startDistance;break}if(r&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();let c=!1,h=-1,l=-1;for(let t=o+1;t<=i;t++)if(this.jumperPadPointIndices.has(t)){c=!0,h=t,l=t>0&&t-1<this.pathSegments.length?this.pathSegments[t-1].endDistance:this.pathSegments[0]?.startDistance??0;break}if(c&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();if(c&&h>=0){const t=this.inputRoute.route[h];this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const e=this.newRoute[this.newRoute.length-1];return e&&e.x===t.x&&e.y===t.y||this.newRoute.push({x:t.x,y:t.y,z:t.z}),this.currentStepSize=this.maxStepSize,this.tailDistanceAlongPath=l,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,void(this.lastValidPathHeadDistance=this.tailDistanceAlongPath)}if(r&&a>0){const t=this.getNearestIndexForDistance(a)+1,e=this.inputRoute.route[t],n={x:e.x,y:e.y};this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const s=this.newRoute[this.newRoute.length-1];s.x===n.x&&s.y===n.y||this.newRoute.push({x:n.x,y:n.y,z:s.z}),this.newVias.push(n),this.newRoute.push({x:n.x,y:n.y,z:e.z}),this.currentStepSize=this.maxStepSize;const o=this.pathSegments.findIndex(t=>t.start===e);if(-1!==o)this.tailDistanceAlongPath=this.pathSegments[o].startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath;else if(t<this.inputRoute.route.length){if(t===this.inputRoute.route.length-1)return void(this.solved=!0);console.warn("Fallback used for tailDistanceAlongPath after layer change");const e=this.pathSegments.find(e=>e.start===this.inputRoute.route[t]);e?(this.tailDistanceAlongPath=e.startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath):(console.error(`[${this.inputRoute.connectionName}] Could not find segment start after layer change. Path might be incomplete.\n Index sought: ${t}, Point: (${this.inputRoute.route[t].x.toFixed(3)}, ${this.inputRoute.route[t].y.toFixed(3)}, z=${this.inputRoute.route[t].z})\n Route Length: ${this.inputRoute.route.length}, Path Segments: ${this.pathSegments.length}`),this.solved=!0)}else console.warn("Layer change occurred at the end of the path."),this.solved=!0;return}const d=this.find45DegreePath(n,s);if(!d&&this.lastHeadMoveDistance>this.minStepSize)this.stepBackAndReduceStepSize();else{if(!d&&!this.lastValidPath){const t=this.getPointAtDistance(this.tailDistanceAlongPath);this.tailDistanceAlongPath+=this.minStepSize,this.moveHead(this.minStepSize);const e=this.getNearestIndexForDistance(this.tailDistanceAlongPath),n=this.inputRoute.route[e],s=this.inputRoute.route[this.inputRoute.route.length-1];return void(this.arePointsEqual(t,n)||this.arePointsEqual(n,s)||this.newRoute.push(n))}if(d)return this.lastValidPath=d,void(this.lastValidPathHeadDistance=this.headDistanceAlongPath);this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null,this.tailDistanceAlongPath=this.lastValidPathHeadDistance,this.moveHead(this.minStepSize))}}visualize(){const t=this.getVisualsForNewRouteAndObstacles(),e=this.getPointAtDistance(this.tailDistanceAlongPath),n=this.getPointAtDistance(this.headDistanceAlongPath);t.points.push({x:e.x,y:e.y,color:"yellow",label:["Tail",`z: ${e.z}`].join("\n")}),t.points.push({x:n.x,y:n.y,color:"orange",label:["Head",`z: ${n.z}`].join("\n")});const s=this.getPointAtDistance(this.headDistanceAlongPath+this.currentStepSize);t.points.push({x:s.x,y:s.y,color:"red",label:["Tentative Head",`z: ${s.z}`].join("\n")});let o=0;for(;o<this.totalPathLength;){const e=this.getPointAtDistance(o);t.circles.push({center:{x:e.x,y:e.y},radius:.05,fill:"rgba(100, 100, 100, 0.5)"}),o+=this.totalPathLength/20}if(this.lastValidPath&&this.lastValidPath.length>1)for(let e=0;e<this.lastValidPath.length-1;e++)t.lines.push({points:[{x:this.lastValidPath[e].x,y:this.lastValidPath[e].y},{x:this.lastValidPath[e+1].x,y:this.lastValidPath[e+1].y}],strokeColor:"rgba(0, 255, 255, 0.9)",strokeDash:"3, 3"});return t}},Nl=class extends Ln{getSolverName(){return"MultiSimplifiedPathSolver"}simplifiedHdRoutes;currentUnsimplifiedHdRouteIndex=0;activeSubSolver=null;unsimplifiedHdRoutes;obstacles;connMap;colorMap;outline;defaultViaDiameter;constructor(t){super(),this.MAX_ITERATIONS=1e8,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes;const e=Math.max(2,...t.unsimplifiedHdRoutes.flatMap(t=>t.route.map(t=>t.z+1)))||2;this.obstacles=ll(t.obstacles,e),this.connMap=t.connMap||new An({}),this.colorMap=t.colorMap||{},this.outline=t.outline,this.defaultViaDiameter=t.defaultViaDiameter??.3,this.simplifiedHdRoutes=[]}_step(){const t=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];if(!this.activeSubSolver)return t?(this.activeSubSolver=new Ml({inputRoute:t,otherHdRoutes:this.unsimplifiedHdRoutes.slice(this.currentUnsimplifiedHdRouteIndex+1).concat(this.simplifiedHdRoutes),obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline}),void this.currentUnsimplifiedHdRouteIndex++):void(this.solved=!0);this.activeSubSolver.step(),this.activeSubSolver.solved&&(this.simplifiedHdRoutes.push(this.activeSubSolver.simplifiedRoute),this.activeSubSolver=null)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Multi Simplified Path Solver"};for(const e of this.unsimplifiedHdRoutes)if(!this.simplifiedHdRoutes.some(t=>t.connectionName===e.connectionName)){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeColor:1===e.route[n].z?"rgba(0, 0, 255, 0.4)":"rgba(255, 0, 0, 0.4)",strokeWidth:.15,strokeDash:1===e.route[n].z?[.5,.5]:void 0});for(const n of e.vias||[])t.circles.push({center:n,radius:(e.viaDiameter??this.defaultViaDiameter)/2,fill:"rgba(0, 0, 255, 0.4)"})}for(const e of this.simplifiedHdRoutes){const n=this.colorMap?.[e.connectionName]||"rgba(128, 128, 128, 0.8)";for(let s=0;s<e.route.length-1;s++)t.lines.push({points:[{x:e.route[s].x,y:e.route[s].y},{x:e.route[s+1].x,y:e.route[s+1].y}],strokeWidth:.15,strokeColor:n,strokeDash:1===e.route[s].z?[.5,.5]:void 0,step:1});for(const n of e.vias||[])t.circles.push({center:n,radius:e.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)",step:1})}for(const e of this.unsimplifiedHdRoutes){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:"rgba(255, 0, 0, 0.2)",strokeDash:[.5,.5],step:0,layer:`z${e.route[n].z.toString()}`});for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 0, 0.2)",step:0})}for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});if(this.currentUnsimplifiedHdRouteIndex<this.unsimplifiedHdRoutes.length){const e=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];e.route.length>0&&t.circles.push({center:{x:e.route[0].x,y:e.route[0].y},radius:.2,fill:"yellow",label:"Current"})}return t}},Il=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:ll(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.inputHdRoutes=this.input.inputHdRoutes,this.mergedViaHdRoutes=structuredClone(this.inputHdRoutes),this.unprocessedRoutes=[...this.input.inputHdRoutes],this.colorMap=this.input.colorMap,this.outline=this.input.outline,this.obstacles=this.input.obstacles,this.obstacleSHI=new nl("flatbush",this.input.obstacles),this.hdRouteSHI=new cl(this.inputHdRoutes),this.vias=[],this.offendingVias=[],this.connMap=t.connMap,this.viasByNet=new Map,this.rebuildVias()}getSolverName(){return"SameNetViaMergerSolver"}inputHdRoutes;mergedViaHdRoutes;unprocessedRoutes;vias;offendingVias;currentViaRoutes=[];connMap;colorMap;outline;obstacles;viasByNet;obstacleSHI=null;hdRouteSHI=null;rebuildVias(){this.vias=[],this.viasByNet=new Map;for(let t=0;t<this.mergedViaHdRoutes.length;t++){const e=this.mergedViaHdRoutes[t];for(let n=0;n<e.vias.length;n++){const s=e.vias[n],o={x:s.x,y:s.y,diameter:e.viaDiameter,net:this.connMap?.idToNetMap[e.connectionName]??"",layers:[...new Set(e.route.map(t=>t.z))],routeIndex:t};this.vias.push(o);const i=this.viasByNet.get(o.net);i?i.push(o):this.viasByNet.set(o.net,[o])}}}findNextOffendingPair(){for(let t=0;t<this.vias.length-1;t++){const e=this.vias[t],n=this.viasByNet.get(e.net);if(!n)continue;const s=n.indexOf(e);for(let t=s>=0?s+1:0;t<n.length;t++){const s=n[t],o=e.x-s.x,i=e.y-s.y,r=o*o+i*i,a=e.diameter/2+s.diameter/2;if(r<=a*a&&0!==r)return[e,s]}}return null}handleOffendingPair(t,e){const n=t.layers.length<e.layers.length?t:e,s=n===t?e:t,o=this.mergedViaHdRoutes[n.routeIndex].route;for(let t=0;t<n.layers.length;t++)for(let t=o.length-1;t>=1;t--){const e=o[t-1],i=o[t];if(i.x===n.x&&i.y===n.y){o.splice(t,0,{x:s.x,y:s.y,z:i.z}),o.splice(t,0,{x:s.x,y:s.y,z:e.z});const r=this.mergedViaHdRoutes[n.routeIndex];return r.vias=r.vias.map(t=>t.x===n.x&&t.y===n.y?{x:s.x,y:s.y}:t),void this.rebuildVias()}}this.rebuildVias()}_step(){const t=this.findNextOffendingPair();t?this.handleOffendingPair(t[0],t[1]):this.solved=!0}getMergedViaHdRoutes(){return this.mergedViaHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Same Net Via Merger Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.mergedViaHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"rgba(255, 0, 0, 0.5)":"rgba(0, 0, 255, 0.5)",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Gh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},_l=class extends Ln{constructor(t){super(),this.simplificationConfig=t,this.simplificationConfig={...t,obstacles:ll(t.obstacles,t.layerCount)},this.hdRoutes=[...t.hdRoutes],this.MAX_ITERATIONS=1e8}getSolverName(){return"TraceSimplificationSolver"}hdRoutes=[];simplificationPipelineLoops=0;MAX_SIMPLIFICATION_PIPELINE_LOOPS=2;PHASE_ORDER=["via_removal","via_merging","path_simplification"];currentPhase="via_removal";extractResult=null;get simplifiedHdRoutes(){return this.hdRoutes}_step(){if(this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)this.solved=!0;else{if(this.activeSubSolver){if(this.activeSubSolver.step(),!this.activeSubSolver.failed&&!this.activeSubSolver.solved)return;if(this.activeSubSolver.solved){if(this.extractResult&&(this.hdRoutes=this.extractResult(this.activeSubSolver)),this.activeSubSolver=null,this.extractResult=null,"via_removal"===this.currentPhase?this.currentPhase="via_merging":"via_merging"===this.currentPhase?this.currentPhase="path_simplification":(this.currentPhase="via_removal",this.simplificationPipelineLoops++),this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)return void(this.solved=!0)}else if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error??"Sub-solver failed without error message")}if(!this.activeSubSolver&&!this.solved)switch(this.currentPhase){case"via_removal":this.activeSubSolver=new dl({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount}),this.extractResult=t=>t.getOptimizedHdRoutes()??[];break;case"via_merging":this.activeSubSolver=new Il({inputHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount,connMap:this.simplificationConfig.connMap,outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0}),this.extractResult=t=>t.getMergedViaHdRoutes()??[];break;case"path_simplification":this.activeSubSolver=new Nl({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,colorMap:{...this.simplificationConfig.colorMap},outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,defaultViaDiameter:this.simplificationConfig.defaultViaDiameter}),this.extractResult=t=>t.simplifiedHdRoutes;break;default:this.failed=!0,this.error=`Unknown phase: ${this.currentPhase}`}}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Trace Simplification Solver"};for(const e of this.simplificationConfig.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.hdRoutes)if(0!==e.route.length){for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Gh(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},Cl=class extends Ln{getSolverName(){return"TraceWidthSolver"}hdRoutes;hdRoutesWithWidths=[];nominalTraceWidth;minTraceWidth;obstacleMargin;TRACE_WIDTH_SCHEDULE;connectionNominalTraceWidthMap;unprocessedRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;currentScheduleIndex=0;currentTargetWidth=0;hasInsufficientClearance=!1;lastCollidingObstacles=[];lastCollidingRoutes=[];lastClearance=1/0;obstacles=[];obstacleSHI;hdRouteSHI;connMap;colorMap;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.hdRoutes=[...t.hdRoutes],this.minTraceWidth=t.minTraceWidth,this.obstacleMargin=t.obstacleMargin??.15,this.nominalTraceWidth=0,this.TRACE_WIDTH_SCHEDULE=[],this.unprocessedRoutes=[...this.hdRoutes],this.connMap=t.connMap,this.colorMap=t.colorMap;const e=t.layerCount;this.obstacles=ll(t.obstacles??[],e),this.connectionNominalTraceWidthMap=new Map;for(const e of t.connection)void 0!==e.nominalTraceWidth&&this.connectionNominalTraceWidthMap.set(e.name,e.nominalTraceWidth);this.obstacles.length>0&&(this.obstacleSHI=new nl("flatbush",this.obstacles)),this.hdRouteSHI=new cl(this.hdRoutes)}getNominalTraceWidthForRoute(t){const e=this.connectionNominalTraceWidthMap.get(t.connectionName);return void 0!==e?e:t.rootConnectionName?this.connectionNominalTraceWidthMap.get(t.rootConnectionName):void 0}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.hdRoutesWithWidths=this.processedRoutes,void(this.solved=!0);const e=this.getNominalTraceWidthForRoute(t);if(void 0===e)return this.processedRoutes.push({...t}),void(this.currentTrace=null);this.currentTrace=t,this.nominalTraceWidth=e;const n=(this.nominalTraceWidth+this.minTraceWidth)/2;return this.TRACE_WIDTH_SCHEDULE=[this.nominalTraceWidth,n],this.currentTrace.route.length<2?(this.processedRoutes.push({...this.currentTrace,traceThickness:this.minTraceWidth}),void(this.currentTrace=null)):(this.currentScheduleIndex=0,this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[0],void this.initializeCursor())}if(!this.stepCursorForward())return void this.finalizeCurrentTrace(this.currentTargetWidth);this.getClearanceAtPosition(this.cursorPosition)<this.currentTargetWidth/2+this.obstacleMargin&&(this.hasInsufficientClearance=!0,this.currentScheduleIndex++,this.currentScheduleIndex<this.TRACE_WIDTH_SCHEDULE.length?(this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[this.currentScheduleIndex],this.initializeCursor()):this.finalizeCurrentTrace(this.minTraceWidth))}initializeCursor(){if(!this.currentTrace)return;const t=this.currentTrace.route[0];this.cursorPosition={...t},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,this.hasInsufficientClearance=!1}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return!1;const t=this.currentTrace.route;let e=.1;for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return!1;const n=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1];if(n.insideJumperPad&&s.insideJumperPad){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const o=s.x-n.x,i=s.y-n.y,r=Math.sqrt(o*o+i*i);if(0===r){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const a=this.currentTraceSegmentT*r,c=r-a;if(e<=c){const t=a+e;return this.currentTraceSegmentT=t/r,this.cursorPosition={x:n.x+o*this.currentTraceSegmentT,y:n.y+i*this.currentTraceSegmentT,z:n.z},!0}if(e-=c,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},!1}}return!0}isObstacleOwnJumperPad(t){if(!this.currentTrace?.jumpers)return!1;for(const e of this.currentTrace.jumpers){const n=Math.sqrt((t.center.x-e.start.x)**2+(t.center.y-e.start.y)**2),s=Math.sqrt((t.center.x-e.end.x)**2+(t.center.y-e.end.y)**2),o=Math.max(t.width,t.height)/2+.01;if(n<o||s<o)return!0}return!1}getClearanceAtPosition(t){if(!this.currentTrace)return 1/0;const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.nominalTraceWidth;let s=1/0;if(this.lastCollidingObstacles=[],this.lastCollidingRoutes=[],this.obstacleSHI){const o=this.obstacleSHI.searchArea(t.x,t.y,n,n);for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.connMap?.areIdsConnected(e,n.obstacleId))continue;let o=!1;if(this.connMap)for(const t of n.connectedTo)if(this.connMap.areIdsConnected(e,t)){o=!0;break}if(o)continue;if(this.isObstacleOwnJumperPad(n))continue;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,a=n.center.y-n.height/2,c=n.center.y+n.height/2,h=Math.max(i-t.x,0,t.x-r),l=Math.max(a-t.y,0,t.y-c),d=Math.sqrt(h*h+l*l);d<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingObstacles.push(n),d<s&&(s=d)}}const o=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:t,distance:n}of o){const o=t.rootConnectionName??t.connectionName;if(o===e)continue;if(this.connMap?.areIdsConnected(e,o))continue;const i=n-(t.traceThickness??.15)/2;i<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingRoutes.push(t),i<s&&(s=i)}return this.lastClearance=s,s}finalizeCurrentTrace(t){if(!this.currentTrace)return;const e={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:t,viaDiameter:this.currentTrace.viaDiameter,route:[...this.currentTrace.route],vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(e),this.currentTrace=null,this.cursorPosition=null,this.hasInsufficientClearance=!1}visualize(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:`Trace Width Solver (schedule: [${this.TRACE_WIDTH_SCHEDULE.map(t=>t.toFixed(2)).join(", ")}]mm, fallback: ${this.minTraceWidth.toFixed(2)}mm, margin: ${this.obstacleMargin.toFixed(2)}mm)`},e=new Set(this.lastCollidingObstacles.map(t=>t.obstacleId)),n=new Set(this.lastCollidingRoutes.map(t=>t.connectionName));for(const n of this.obstacles){const s=e.has(n.obstacleId),o=n.zLayers?.includes(0),i=n.zLayers?.includes(1);let r;r=s?"rgba(255, 0, 0, 0.6)":o&&i?"rgba(128, 0, 128, 0.15)":o?"rgba(255, 0, 0, 0.15)":i?"rgba(0, 0, 255, 0.15)":"rgba(128, 128, 128, 0.15)",t.rects.push({center:n.center,width:n.width,height:n.height,fill:r,stroke:s?"red":void 0,label:s?`COLLIDING: ${n.obstacleId??"obstacle"}`:`${n.obstacleId??"obstacle"} (Z: ${n.zLayers?.join(", ")})`})}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=e.traceThickness===this.nominalTraceWidth,s=e.traceThickness===this.TRACE_WIDTH_SCHEDULE[1],o=n?"green":s?"yellow":"orange";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],i=e.route[n+1];s.insideJumperPad&&i.insideJumperPad||s.z===i.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:i.x,y:i.y}],strokeColor:o,strokeWidth:e.traceThickness,label:`${e.connectionName} (w=${e.traceThickness.toFixed(2)})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Gh(e.jumpers,{color:o,label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}if(this.currentTrace){for(let e=0;e<this.currentTrace.route.length-1;e++){const n=this.currentTrace.route[e],s=this.currentTrace.route[e+1];n.insideJumperPad&&s.insideJumperPad||n.z===s.z&&t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"cyan",strokeWidth:this.currentTrace.traceThickness??this.minTraceWidth,label:`Processing: ${this.currentTrace.connectionName}`})}this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentTargetWidth/2,stroke:this.hasInsufficientClearance?"red":"green",fill:"none",label:`Testing width: ${this.currentTargetWidth.toFixed(2)}mm (clearance: ${this.lastClearance.toFixed(2)}mm)`}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}))}for(const e of this.unprocessedRoutes){if(0===e.route.length)continue;const s=n.has(e.connectionName);for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:s?"rgba(255, 0, 0, 0.8)":"rgba(128, 128, 128, 0.3)",strokeWidth:e.traceThickness??this.minTraceWidth,label:s?`COLLIDING: ${e.connectionName}`:e.connectionName})}}return t}getHdRoutesWithWidths(){return this.hdRoutesWithWidths}};function Tl(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var El=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipelineSolver2_PortPointPathing"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;inputNodeWithPortPoints=[];cacheProvider=null;pipelineDef=[Tl("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Tl("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Tl("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Tl("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Tl("portPointPathingSolver",zh,t=>{this.inputNodeWithPortPoints=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle}));const e=new Map(this.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,t])),n=t.availableSegmentPointSolver;for(const t of n.sharedEdgeSegments)for(const n of t.portPoints){const[t,s]=n.nodeIds,o={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,s],distToCentermostPortOnZ:n.distToCentermostPortOnZ},i=e.get(t);i&&i.portPoints.push(o)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:this.inputNodeWithPortPoints,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:200,hyperParameters:{NODE_PF_MAX_PENALTY:100,FORCE_OFF_BOARD_FREQUENCY:0,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4}}]}),Tl("multiSectionPortPointOptimizer",Fh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints,effort:t.effort}]}),Tl("uniformPortDistributionSolver",ze,t=>[{nodeWithPortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Tl("highDensityRouteSolver",uh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),Tl("highDensityStitchSolver",Qh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Tl("traceSimplificationSolver",_l,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Tl("traceWidthSolver",Cl,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.srj.outline,m=[];if(m.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),f&&f.length>=2){const t=f.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),m.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const g={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:m},y=[g,t,e,n,s,o,i,r,a,c,h,l,d?jn(g,d):null,u,p,this.solved?jn(g,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...y)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},wl=El,Rl=class extends Ln{getSolverName(){return"CapacityEdgeToPortSegmentSolver"}nodes;edges;capacityPaths;nodeMap;nodeEdgeMap;unprocessedNodeIds;nodePortSegments;colorMap;constructor({nodes:t,edges:e,capacityPaths:n,colorMap:s}){super(),this.nodes=t,this.edges=e,this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(e),this.capacityPaths=n,this.colorMap=s??{},this.unprocessedNodeIds=[...new Set(n.flatMap(t=>t.nodeIds))],this.nodePortSegments=new Map}step(){const t=this.unprocessedNodeIds.pop();if(!t)return void(this.solved=!0);const e=[];for(const n of this.capacityPaths){const s=n.nodeIds.indexOf(t);-1!==s&&e.push({path:n,indexOfNodeInPath:s})}const n=this.nodeMap.get(t),s=[];for(const{path:o,indexOfNodeInPath:i}of e){const e=o.nodeIds[i-1],r=o.nodeIds[i+1];for(const i of[e,r]){const e=this.nodeMap.get(i);if(!e)continue;const r=Ol(n,e),a=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===a.length)continue;const c={capacityMeshNodeId:t,start:r.start,end:r.end,connectionNames:[o.connectionName],rootConnectionNames:o.rootConnectionName?[o.rootConnectionName]:void 0,availableZ:a};s.push(c)}}const o=function(t){const e=[],n=t.map(t=>({...t,connectionNames:[...t.connectionNames],rootConnectionNames:t.rootConnectionNames?[...t.rootConnectionNames]:[],availableZ:[...t.availableZ].sort((t,e)=>t-e)}));for(;n.length>0;){const t=n.pop();let s=!1;for(let n=0;n<e.length;n++){const o=e[n],i=zl(o.start,t.start)&&zl(o.end,t.end)||zl(o.start,t.end)&&zl(o.end,t.start),r=Dl(o.availableZ,t.availableZ);if(i&&r){const e=new Set(o.connectionNames);t.connectionNames.forEach(t=>e.add(t)),o.connectionNames=Array.from(e);const n=new Set(o.rootConnectionNames||[]);t.rootConnectionNames?.forEach(t=>n.add(t)),o.rootConnectionNames=Array.from(n),s=!0;break}}s||e.push(t)}return e}(s);this.nodePortSegments.set(t,o)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};return this.nodePortSegments.forEach((e,n)=>{this.nodeMap.get(n);e.forEach(e=>{e.start.x,e.end.x;for(let s=0;s<e.connectionNames.length;s++){const o={x:.05*Math.max(...e.availableZ),y:.05*Math.max(...e.availableZ)},i={x:(e.start.x+e.end.x)/2,y:(e.start.y+e.end.y)/2},r={x:i.x+o.x,y:i.y+o.y};o.x>0&&t.lines.push({points:[i,r],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5"}),t.points.push({x:r.x,y:r.y,label:`${n}: ${e.connectionNames.join(", ")}\navailableZ: ${e.availableZ.join(",")}\nnodePortSegmentId: ${e.nodePortSegmentId}`}),t.lines.push({points:[e.start,e.end],strokeColor:In(this.colorMap[e.connectionNames[s]],.6)})}})}),t}};function Ol(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)};if(n.end-n.start<s.end-s.start){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}var Al=1e-9;function zl(t,e){return Math.abs(t.x-e.x)<Al&&Math.abs(t.y-e.y)<Al}function Dl(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}var Ll=class{constructor(t){this.targets=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=Math.floor(n.bounds.minX/this.CELL_SIZE)*this.CELL_SIZE,o=Math.floor(n.bounds.minY/this.CELL_SIZE)*this.CELL_SIZE,i=n.bounds.maxX,r=n.bounds.maxY;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=5;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getTargetsInArea(t,e,n,s){const o=[],i=new Set,r=Math.floor((t-n/2)/this.CELL_SIZE)*this.CELL_SIZE,a=Math.floor((e-s/2)/this.CELL_SIZE)*this.CELL_SIZE,c=t+n/2,h=e+s/2;for(let t=r;t<=c;t+=this.CELL_SIZE)for(let e=a;e<=h;e+=this.CELL_SIZE){const n=this.getBucketKey(t,e),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},Fl=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.MAX_DEPTH=e?.capacityDepth??this.MAX_DEPTH,this.MAX_ITERATIONS=1e5,this.layerCount=t.layerCount??2,this.outlinePolygon=t.outline&&t.outline.length>=3?t.outline:void 0;const n={x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},s={width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},o=Math.max(s.width,s.height);this.unfinishedNodes=[{capacityMeshNodeId:this.getNextNodeId(),center:n,width:o,height:o,layer:"top",availableZ:Array.from({length:this.layerCount},(t,e)=>e),_depth:0,_containsTarget:!0,_containsObstacle:!0,_completelyInsideObstacle:!1}],this.finishedNodes=[],this.nodeToXYOverlappingObstaclesMap=new Map,this.obstacleZLayersByObstacle=new WeakMap;const i=ll(this.srj.obstacles,this.layerCount);for(const[t,e]of this.srj.obstacles.entries())this.obstacleZLayersByObstacle.set(e,i[t].zLayers);this.obstacleTree=new nl("flatbush",this.srj.obstacles),this.targets=this.computeTargets(),this.targetTree=new Ll(this.targets)}getSolverName(){return"CapacityMeshNodeSolver"}unfinishedNodes;finishedNodes;nodeToXYOverlappingObstaclesMap;layerCount;outlinePolygon;MAX_DEPTH=4;targets;targetTree;obstacleTree;obstacleZLayersByObstacle;computeTargets(){const t=[];for(const e of this.srj.connections)for(const n of e.pointsToConnect){const s=En(n),o=this.obstacleTree.searchArea(n.x,n.y,.01,.01).filter(t=>{const e=this.getObstacleZLayers(t);return!(!e||0===e.length)&&e.some(t=>s.some(e=>t===Rn(e,this.layerCount)))});let i={minX:n.x-.005,minY:n.y-.005,maxX:n.x+.005,maxY:n.y+.005};o.length>0&&(i={minX:Math.min(...o.map(t=>t.center.x-t.width/2)),minY:Math.min(...o.map(t=>t.center.y-t.height/2)),maxX:Math.max(...o.map(t=>t.center.x+t.width/2)),maxY:Math.max(...o.map(t=>t.center.y+t.height/2))});const r={...n,connectionName:e.name,availableZ:s.map(t=>Rn(t,this.layerCount)),bounds:i};t.push(r)}return t}getNodeBounds(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}getNodeRect(t){return{center:{x:t.center.x,y:t.center.y},width:t.width,height:t.height}}_nextNodeCounter=0;getNextNodeId(){return"cn"+this._nextNodeCounter++}getCapacityFromDepth(t){return(this.MAX_DEPTH-t+1)**2}getTargetIfNodeContainsTarget(t){const e=t.width>4*this.targetTree.CELL_SIZE?this.targets:this.targetTree.getTargetsInArea(t.center.x,t.center.y,t.width,t.height);for(const n of e)if(n.bounds.minX<=t.center.x+t.width/2&&n.bounds.maxX>=t.center.x-t.width/2&&n.bounds.minY<=t.center.y+t.height/2&&n.bounds.maxY>=t.center.y-t.height/2&&n.availableZ.some(e=>t.availableZ.includes(e)))return n;return null}getXYOverlappingObstacles(t){const e=this.nodeToXYOverlappingObstaclesMap.get(t.capacityMeshNodeId);if(e)return e;const n=[],s=this.getNodeBounds(t),o=s.minX,i=s.maxX,r=s.minY,a=s.maxY,c=t._parent?this.getXYOverlappingObstacles(t._parent):this.srj.obstacles;for(const t of c){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,c=t.center.y-t.height/2,h=t.center.y+t.height/2;i>=e&&o<=s&&a>=c&&r<=h?n.push(t):(o>=e&&i<=s&&r>=c&&a<=h||e>=o&&s<=i&&c>=r&&h<=a)&&n.push(t)}return this.nodeToXYOverlappingObstaclesMap.set(t.capacityMeshNodeId,n),n}getXYZOverlappingObstacles(t){const e=this.getXYOverlappingObstacles(t),n=[];for(const s of e)t.availableZ.some(t=>this.getObstacleZLayers(s).includes(t))&&n.push(s);return n}doesNodeOverlapObstacle(t){if(this.getXYZOverlappingObstacles(t).length>0)return!0;const e=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!J(e,this.outlinePolygon))return!0}return e.minX<this.srj.bounds.minX||e.maxX>this.srj.bounds.maxX||e.minY<this.srj.bounds.minY||e.maxY>this.srj.bounds.maxY}isNodeCompletelyInsideObstacle(t){const e=this.getXYZOverlappingObstacles(t),n=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}for(const t of e){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2;if(n.minX>=e&&n.maxX<=s&&n.minY>=o&&n.maxY<=i)return!0}return!1}getChildNodes(t){if(t._depth===this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s={capacityMeshNodeId:this.getNextNodeId(),center:o,width:n.width,height:n.height,layer:t.layer,availableZ:t.availableZ,_depth:(t._depth??0)+1,_parent:t};s._containsObstacle=this.doesNodeOverlapObstacle(s);const i=this.getTargetIfNodeContainsTarget(s);i&&(s._targetConnectionName=i.connectionName,s.availableZ=i.availableZ,s._containsTarget=!0),s._containsObstacle&&(s._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(s)),s._completelyInsideObstacle&&!s._containsTarget||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||!(!t._containsObstacle||t._completelyInsideObstacle))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t);e?s.push(t):e||t._containsObstacle?!e&&t._containsTarget&&n.push(t):n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Mesh Visualization"};if(this.outlinePolygon&&this.outlinePolygon.length>=2){const e=this.outlinePolygon.map(t=>({x:t.x,y:t.y}));e.push({...e[0]}),t.lines.push({points:e,strokeColor:"rgba(0, 136, 255, 0.95)",label:"outline"});for(const e of this.outlinePolygon)t.points.push({x:e.x,y:e.y,color:"rgba(0, 136, 255, 0.95)"})}for(const e of this.srj.obstacles){const n=this.getObstacleZLayers(e);t.rects.push({center:e.center,width:e.width,height:e.height,fill:1===n.length&&n.includes(1)?"rgba(0,0,255,0.3)":"rgba(255,0,0,0.3)",stroke:"red",label:["obstacle",`z: ${n.join(",")}`].join("\n")})}const e=[...this.finishedNodes,...this.unfinishedNodes];for(const n of e){const e=Math.min(...n.availableZ),s=this.unfinishedNodes.length>0&&n===this.unfinishedNodes[this.unfinishedNodes.length-1];t.rects.push({center:{x:n.center.x+e*n.width*.05,y:n.center.y-e*n.width*.05},width:Math.max(n.width-2,.8*n.width),height:Math.max(n.height-2,.8*n.height),fill:n._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[n.availableZ.join(",")]??"rgba(0,200,200,0.1)",stroke:s?"rgba(255,165,0,0.5)":void 0,label:[n.capacityMeshNodeId,`availableZ: ${n.availableZ.join(",")}`,`target? ${n._containsTarget??!1}`,`obs? ${n._containsObstacle??!1}`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`capacity: ${vh(n).toFixed(2)}`].join("\n")})}return t.rects.sort((t,e)=>t.center.y-e.center.y),this.srj.connections.forEach((e,n)=>{const s=Mn[n%Mn.length];for(const o of e.pointsToConnect){const e=En(o);t.points.push({x:o.x,y:o.y,label:`conn-${n} (${e.join(",")})`,color:s})}}),t}getObstacleZLayers(t){return this.obstacleZLayersByObstacle.get(t)??[]}},Yl=class extends Fl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e,this.VIA_DIAMETER=t.minViaDiameter??this.VIA_DIAMETER}getSolverName(){return"CapacityMeshNodeSolver2_NodeUnderObstacle"}VIA_DIAMETER=.6;OBSTACLE_MARGIN=.1;OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES=.2;isNodeCompletelyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}return t.center.x+t.width/2<this.srj.bounds.minX||t.center.x-t.width/2>this.srj.bounds.maxX||t.center.y+t.height/2<this.srj.bounds.minY||t.center.y-t.height/2>this.srj.bounds.maxY}isNodePartiallyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);return!!q(e,this.outlinePolygon)&&!J(e,this.outlinePolygon)}return t.center.x-t.width/2<this.srj.bounds.minX||t.center.x+t.width/2>this.srj.bounds.maxX||t.center.y-t.height/2<this.srj.bounds.minY||t.center.y+t.height/2>this.srj.bounds.maxY}getObstacleCoveragePercentage(t){const e=this.getXYZOverlappingObstacles(t);if(0===e.length)return 0;const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=t.width*t.height;let a=0;for(const t of e){const e=Math.max(n,t.center.x-t.width/2),r=Math.min(s,t.center.x+t.width/2),c=Math.max(o,t.center.y-t.height/2),h=Math.min(i,t.center.y+t.height/2);if(e<r&&c<h){a+=(r-e)*(h-c)}}return a/r}shouldFilterSingleLayerNodeForObstacle(t){if(1!==t.availableZ.length)return!1;if(!t._containsObstacle)return!1;return this.getObstacleCoveragePercentage(t)>this.OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES}shouldFilterNodeForObstacle(t){return!!t._containsObstacle&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}createChildNodeAtPosition(t,e){const n={capacityMeshNodeId:this.getNextNodeId(),center:e.center,width:e.width,height:e.height,layer:t.layer,availableZ:e.availableZ,_depth:e._depth??(t._depth??0)+1,_parent:t},s=this.getXYZOverlappingObstacles(n);n._containsObstacle=s.length>0||this.isNodePartiallyOutsideBounds(n);const o=this.getTargetIfNodeContainsTarget(n);return o&&(n._targetConnectionName=o.connectionName,n._containsTarget=!0),n._containsObstacle&&(n._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(n)),n}getZSubdivisionChildNodes(t){if(1===t.availableZ.length)return[];const e=[],n=t.availableZ.map(t=>[t]);for(const s of n){const n=this.createChildNodeAtPosition(t,{center:{...t.center},width:t.width,height:t.height,availableZ:s,_depth:t._depth});this.isNodeCompletelyOutsideBounds(n)||e.push(n)}return e}getChildNodes(t){if(t._depth>=this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s=this.createChildNodeAtPosition(t,{center:o,width:n.width,height:n.height,availableZ:t.availableZ});this.isNodeCompletelyOutsideBounds(s)||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(1===t.availableZ.length&&t._depth<=this.MAX_DEPTH||!(!t._containsObstacle||t._completelyInsideObstacle)))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e&&(t._containsObstacle||t.width<this.VIA_DIAMETER+this.OBSTACLE_MARGIN);if(e)s.push(t);else if(e||this.shouldFilterNodeForObstacle(t)||o)if(!e&&t._containsTarget)if(o){const e=this.getZSubdivisionChildNodes(t);n.push(...e.filter(t=>t._containsTarget||!this.shouldFilterNodeForObstacle(t)))}else n.push(t);else o&&n.push(...this.getZSubdivisionChildNodes(t).filter(t=>!this.shouldFilterNodeForObstacle(t)));else n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},Xl=class extends Ln{getSolverName(){return"CapacitySegmentToPointSolver"}unsolvedSegments;solvedSegments;nodeMap;colorMap;constructor({segments:t,colorMap:e,nodes:n}){super(),this.MAX_ITERATIONS=1e5,this.unsolvedSegments=t,this.solvedSegments=[],this.colorMap=e??{},this.nodeMap=Object.fromEntries(n.map(t=>[t.capacityMeshNodeId,t]))}_step(){let t=!1;const e=[...this.unsolvedSegments];for(const n of e){const e=n.connectionNames.length;if((!("assignedPoints"in n)||n.assignedPoints?.length!==e)&&1===e){const e={x:(n.start.x+n.end.x)/2,y:(n.start.y+n.end.y)/2,z:n.availableZ[0]};n.assignedPoints=[{connectionName:n.connectionNames[0],rootConnectionName:n.rootConnectionNames?.[0],point:e}],this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}}if(!t&&e.length>0){let n=e[0];for(const t of e)t.connectionNames.length<n.connectionNames.length&&(n=t);const s=[...n.connectionNames].sort(),o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=s.length,a=[];for(let t=1;t<=r;t++){const e=t/(r+1);a.push({x:n.start.x+o*e,y:n.start.y+i*e,z:n.availableZ[0]})}n.assignedPoints=s.map((t,e)=>({connectionName:t,rootConnectionName:n.rootConnectionNames?.[n.connectionNames.indexOf(t)],point:a[e]})),this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}0===this.unsolvedSegments.length&&(this.solved=!0)}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.solvedSegments){const n=e.capacityMeshNodeId,s=this.nodeMap[n];t.has(n)||t.set(n,{capacityMeshNodeId:n,portPoints:[],center:s.center,width:s.width,height:s.height}),t.get(n).portPoints.push(...e.assignedPoints.map(t=>({...t.point,connectionName:t.connectionName})))}return Array.from(t.values())}visualize(){const t={points:[],lines:this.solvedSegments.map(t=>({points:[t.start,t.end],step:4})),rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Segment to Point Solver"};for(let e=0;e<this.solvedSegments.length;e++){const n=this.solvedSegments[e];for(let e=0;e<n.assignedPoints.length;e++){const s=n.assignedPoints[e],o={x:s.point.x,y:s.point.y},i={x:s.point.x+.05*s.point.z,y:s.point.y+.05*s.point.z};0!==s.point.z&&t.lines.push({points:[o,i],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5",step:4}),t.points.push({x:i.x,y:i.y,label:[`${n.capacityMeshNodeId}-${s.connectionName}`,`z: ${n.availableZ.join(",")}`,`nodePortSegmentId: ${n.nodePortSegmentId}`].join("\n"),color:this.colorMap[s.connectionName],step:4})}}const e=[],n={};for(const t of this.solvedSegments){const e=t.capacityMeshNodeId;n[e]||(n[e]={});for(const s of t.assignedPoints)n[e][s.connectionName]||(n[e][s.connectionName]=[]),n[e][s.connectionName].push({x:s.point.x,y:s.point.y})}for(const t in n)for(const s in n[t]){const o=n[t][s];o.length>1&&e.push({points:o,step:4,strokeDash:"5 5",strokeColor:this.colorMap[s]||"#000"})}return t.lines.push(...e),t}},kl=(t,e={})=>{const n=Math.min(...t.availableZ);return{center:!e.rectMargin||e.zOffset?{x:t.center.x+n*t.width*(e.zOffset??.05),y:t.center.y-n*t.width*(e.zOffset??.05)}:t.center,width:e.rectMargin?t.width-2*e.rectMargin:Math.max(t.width-.5,.8*t.width),height:e.rectMargin?t.height-2*e.rectMargin:Math.max(t.height-.5,.8*t.height),fill:t._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[t.availableZ.join(",")]??"rgba(0,200,200,0.1)",layer:`z${t.availableZ.join(",")}`,label:[t.capacityMeshNodeId,`availableZ: ${t.availableZ.join(",")}`,""+(t._containsTarget?"containsTarget":""),""+(t._containsObstacle?"containsObstacle":"")].filter(Boolean).join("\n")}},$l=class extends Ln{getSolverName(){return"CapacityPathingSolver"}connectionsWithNodes;usedNodeCapacityMap;simpleRouteJson;nodes;edges;GREEDY_MULTIPLIER=1.1;MAX_CANDIDATES_IN_MEMORY=1e5;nodeMap;nodeEdgeMap;connectionNameToGoalNodeIds;colorMap;maxDepthOfNodes;activeCandidateStraightLineDistance;debug_lastNodeCostMap;hyperParameters;constructor({simpleRouteJson:t,nodes:e,edges:n,colorMap:s,MAX_ITERATIONS:o=1e6,hyperParameters:i={}}){super(),this.MAX_ITERATIONS=o,this.simpleRouteJson=t,this.nodes=e,this.edges=n,this.colorMap=s??{};const{connectionsWithNodes:r,connectionNameToGoalNodeIds:a}=this.getConnectionsWithNodes();this.connectionsWithNodes=r,this.connectionNameToGoalNodeIds=a,this.hyperParameters=i,this.usedNodeCapacityMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,0])),this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges),this.maxDepthOfNodes=Math.max(...this.nodes.map(t=>t._depth??0)),this.debug_lastNodeCostMap=new Map}getTotalCapacity(t){const e=t._depth??0;return(this.maxDepthOfNodes-e+1)**2}getConnectionsWithNodes(){const t=[],e=this.nodes.filter(t=>t._containsTarget),n=new Map;for(const s of this.simpleRouteJson.connections){const o=[];for(const t of s.pointsToConnect){let n=this.nodes[0],s=Number.MAX_VALUE;for(const o of e){const e=Math.sqrt((o.center.x-t.x)**2+(o.center.y-t.y)**2);e<s&&(s=e,n=o)}o.push(n)}if(o.length<2)throw new Error(`Not enough nodes for connection "${s.name}", only ${o.length} found`);n.set(s.name,o.map(t=>t.capacityMeshNodeId)),t.push({connection:s,nodes:o,pathFound:!1,straightLineDistance:k(o[0].center,o[o.length-1].center)})}return t.sort((t,e)=>t.straightLineDistance-e.straightLineDistance),{connectionsWithNodes:t,connectionNameToGoalNodeIds:n}}currentConnectionIndex=0;candidates;visitedNodes;computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)}getBacktrackedPath(t){const e=[];let n=t;for(;n;)e.push(n.node),n=n.prevCandidate;return e}getNeighboringNodes(t){return this.nodeEdgeMap.get(t.capacityMeshNodeId).flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t))}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,rootConnectionName:e.connection.rootConnectionName,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}doesNodeHaveCapacityForTrace(t,e){const n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=this.getTotalCapacity(t);if(1===t.availableZ.length&&!t._containsTarget&&n>0)return!1;let o=0;return t.availableZ.length>1&&1===e.availableZ.length&&(o+=.5),n+o<s}canTravelThroughObstacle(t,e){const n=this.connectionNameToGoalNodeIds.get(e);return n?.includes(t.capacityMeshNodeId)??!1}getDistanceBetweenNodes(t,e){return Math.sqrt((t.center.x-e.center.x)**2+(t.center.y-e.center.y)**2)}reduceCapacityAlongPath(t){for(const e of t.path??[])this.usedNodeCapacityMap.set(e.capacityMeshNodeId,this.usedNodeCapacityMap.get(e.capacityMeshNodeId)+1)}isConnectedToEndGoal(t,e){return this.nodeEdgeMap.get(t.capacityMeshNodeId).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}_step(){const t=this.connectionsWithNodes[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const[e,n]=t.nodes;this.candidates||(this.candidates=[{prevCandidate:null,node:e,f:0,g:0,h:0}],this.debug_lastNodeCostMap=new Map,this.visitedNodes=new Set([e.capacityMeshNodeId]),this.activeCandidateStraightLineDistance=k(e.center,n.center)),this.candidates.sort((t,e)=>t.f-e.f);const s=this.candidates.shift();if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!s)return console.error(`Ran out of candidates on connection ${t.connection.name}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,void(this.failed=!0);if(this.isConnectedToEndGoal(s.node,n))return t.path=this.getBacktrackedPath({prevCandidate:s,node:n,f:0,g:0,h:0}),this.reduceCapacityAlongPath(t),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);const o=this.getNeighboringNodes(s.node);for(const t of o){if(this.visitedNodes?.has(t.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(t,s.node))continue;const e=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;if(t._containsObstacle&&!this.canTravelThroughObstacle(t,e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+i*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:r,g:o,h:i});const a={prevCandidate:s,node:t,f:r,g:o,h:i};this.candidates.push(a)}this.visitedNodes.add(s.node.capacityMeshNodeId)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.connectionsWithNodes)for(let e=0;e<this.connectionsWithNodes.length;e++){const n=this.connectionsWithNodes[e];if(n.path&&n.path.length>0){const s=n.path.map(({center:{x:t,y:n},width:s,availableZ:o})=>({x:t+.005*s*(e%10+e%19),y:n+.005*s*(e%10+e%19),availableZ:o}));t.lines.push({points:s,strokeColor:this.colorMap[n.connection.name]});for(let e=0;e<s.length;e++){const o=s[e];t.points.push({x:o.x,y:o.y,label:[`conn: ${n.connection.name}`,`node: ${n.path[e].capacityMeshNodeId}`,`z: ${o.availableZ.join(",")}`].join("\n")})}}}for(const e of this.nodes){const n=this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,s=this.getTotalCapacity(e),o=this.debug_lastNodeCostMap.get(e.capacityMeshNodeId);t.rects.push({...kl(e,{rectMargin:.025,zOffset:.01}),label:[`${e.capacityMeshNodeId}`,`${n}/${s}`,`${e.width.toFixed(2)}x${e.height.toFixed(2)}`,`g: ${void 0!==o?.g?o.g.toFixed(2):"?"}`,`h: ${void 0!==o?.h?o.h.toFixed(2):"?"}`,`f: ${void 0!==o?.f?o.f.toFixed(2):"?"}`,`z: ${e.availableZ.join(", ")}`].join("\n"),stroke:n>s+.5?"red":void 0})}if(this.connectionsWithNodes)for(const e of this.connectionsWithNodes)if(e.connection?.pointsToConnect)for(const n of e.connection.pointsToConnect)t.points.push({x:n.x,y:n.y,label:[`pointsToConnect ${e.connection.name}`].join("\n")});let e=this.connectionsWithNodes[this.currentConnectionIndex];if(!this.candidates&&this.currentConnectionIndex>0&&!this.connectionsWithNodes[this.currentConnectionIndex-1].path&&(e=this.connectionsWithNodes[this.currentConnectionIndex-1]),e){const[n,s]=e.connection.pointsToConnect;t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"red",strokeDash:"10 5"})}if(this.candidates){const e=this.candidates.slice(0,5),n=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;e.forEach((e,s)=>{const o=.5*(1-s/5),i=this.getBacktrackedPath(e);t.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:In(this.colorMap[n]??"red",1-o)})})}return t}},Bl=class extends $l{getSolverName(){return"CapacityPathingSolver5"}NEGATIVE_CAPACITY_PENALTY_FACTOR=1;REDUCED_CAPACITY_PENALTY_FACTOR=1;constructor(...t){super(...t),this.GREEDY_MULTIPLIER=2.5}get maxCapacityFactor(){return this.hyperParameters.MAX_CAPACITY_FACTOR??1}getTotalCapacity(t){return vh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){const e=t.width+t.height,n=.05,s=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0);if(s>2)return n;return(e-n)*Math.max(1,(2-s)/(e-n))+n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}},jl=class extends Bl{getSolverName(){return"CapacityPathingGreedySolver"}doesNodeHaveCapacityForTrace(t,e){return!0}getNodeCapacityPenalty(t){const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+2*Math.abs(e))*n}};function Wl(t,e,n){const s=e.x-t.x,o=e.y-t.y;if(Math.abs(s)<1e-9&&Math.abs(o)<1e-9)return t;const i=n.width/2,r=n.height/2,a=n.center.x-i,c=n.center.x+i,h=n.center.y-r,l=n.center.y+r;let d=0,u=1/0;if(Math.abs(s)>1e-9){const e=(a-t.x)/s,n=(c-t.x)/s;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.x<a||t.x>c)return t;if(Math.abs(o)>1e-9){const e=(h-t.y)/o,n=(l-t.y)/o;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.y<h||t.y>l)return t;if(u<d||d===1/0||d<-1e9)return t;return{x:t.x+s*d,y:t.y+o*d}}function Hl(t,e){const n=t.center,s=e.center,o=Wl(n,s,t),i=Wl(s,n,e),r=s.x-n.x,a=s.y-n.y,c=Math.sqrt(r*r+a*a);let h=o,l=i;if(c>1e-9){const n={x:r/c,y:a/c},s=.3*t.width,d=.3*e.width;s+d<Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)?(h={x:o.x+n.x*s,y:o.y+n.y*s},l={x:i.x-n.x*d,y:i.y-n.y*d}):(h=o,l=i)}return{lineStart:h,lineEnd:l}}var Ul=t=>{const{usedCapacity:e,totalCapacity:n,layerCount:s}=t;if(e<n)return 0;if(n<1&&e<=1)return 0;if(1===s&&e>1)return 1-.01**e;const o=e/n-1;return 1-Math.exp(-2*o)},Vl=(t,e,n)=>{if(n._containsTarget)return 0;if(t<=e)return 0;const s=1-Ul({usedCapacity:t,totalCapacity:e,layerCount:n.availableZ.length});return s<=0?-1e9:Math.log(s)},Gl=({totalNodeCapacityMap:t,usedNodeCapacityMap:e,nodeMap:n,sectionNodeIds:s})=>{let o=0;const i=s??new Set(e.keys());for(const s of i){if(!t.has(s))continue;const i=n.get(s);if(!i)continue;const r=t.get(s),a=e.get(s)??0;o+=Vl(a,r,i)}return o};function Zl({sectionNodes:t,sectionEdges:e,sectionConnectionTerminals:n,completedPaths:s,nodeMap:o,colorMap:i,centerNodeId:r,title:a,nodeOpacity:c=.1,usedNodeCapacityMap:h,totalCapacityMap:l}){const d={points:[],lines:[],rects:[],circles:[],title:a},u=new Set(t.map(t=>t.capacityMeshNodeId));for(const e of t){let t=`rgba(128, 128, 128, ${c})`,n=`rgba(128, 128, 128, ${c})`;const s=e.availableZ??[],o=s.includes(0),i=s.includes(1);o&&i?(t=`rgba(128, 0, 128, ${c})`,n=`rgba(128, 0, 128, ${c})`):o?(t=`rgba(0, 0, 255, ${c})`,n=`rgba(0, 0, 255, ${c})`):i&&(t=`rgba(255, 0, 0, ${c})`,n=`rgba(255, 0, 0, ${c})`),r&&e.capacityMeshNodeId===r&&(t=`rgba(0, 255, 0, ${c})`,n=`rgba(0, 128, 0, ${c})`),d.rects.push({...kl(e),fill:t,stroke:n,label:`${e.capacityMeshNodeId}\n(Section Node)\nZ: ${s.join(",")}`});const a=d.rects.length-1;if(h&&l){const t=h.get(e.capacityMeshNodeId)??0,n=l.get(e.capacityMeshNodeId)??0,s=n>0?(t/n*100).toFixed(1):"N/A",o=Ul({usedCapacity:t,totalCapacity:n,layerCount:e.availableZ.length});d.rects[a].label+=`\n${t.toFixed(1)} / ${n.toFixed(1)}\n${s}% (Pf: ${(100*o).toFixed(1)}%)`,o>.2&&(d.rects[a].stroke=In("red",.7*(.8+c)))}}for(const t of e){const[e,n]=t.nodeIds,s=o.get(e),i=o.get(n);if(s&&i){const{lineStart:t,lineEnd:e}=Hl(s,i);d.lines.push({points:[t,e],strokeColor:`rgba(0, 0, 0, ${.2*Math.min(1,c/.1)})`})}}return n.forEach((t,e)=>{const n=o.get(t.startNodeId),s=o.get(t.endNodeId),r=i[t.connectionName]??"black",a=n&&u.has(n.capacityMeshNodeId),c=s&&u.has(s.capacityMeshNodeId),h=(e+e/50)%5;let l=0,p=0,f=0,m=0;if(a&&n){const e=.02*Math.min(n.width,n.height);l=e*h,p=e*h,d.points.push({x:n.center.x+l,y:n.center.y+p,color:r,label:`Start: ${t.connectionName}\n(${t.startNodeId})`}),d.lines.push({points:[{x:n.center.x,y:n.center.y},{x:n.center.x+l,y:n.center.y+p}],strokeColor:"gray",strokeDash:"2 2"})}if(c&&s){const e=.02*Math.min(s.width,s.height);f=e*h,m=e*h,d.points.push({x:s.center.x+f,y:s.center.y+m,color:r,label:`End: ${t.connectionName}\n(${t.endNodeId})`}),d.lines.push({points:[{x:s.center.x,y:s.center.y},{x:s.center.x+f,y:s.center.y+m}],strokeColor:"gray",strokeDash:"2 2"})}a&&c&&n&&s&&d.lines.push({points:[{x:n.center.x+l,y:n.center.y+p},{x:s.center.x+f,y:s.center.y+m}],strokeColor:r,strokeDash:"5 5"})}),s&&s.forEach((t,e)=>{if(t.path&&t.path.length>0){const n=i[t.connectionName]??"gray",s={x:(e+e/50)%5*.03,y:(e+e/50)%5*.03};d.lines.push({points:t.path.map(({center:{x:t,y:e}})=>({x:t+s.x,y:e+s.y})),strokeColor:In(n,.2)})}}),d}var ql=class extends Ln{getSolverName(){return"CapacityPathingSingleSectionSolver"}GREEDY_MULTIPLIER=1.5;sectionNodes;sectionEdges;sectionConnectionTerminals;nodeMap;nodeEdgeMap;colorMap;usedNodeCapacityMap;totalNodeCapacityMap;centerNodeId;currentSectionScore=0;MAX_CANDIDATES_IN_MEMORY=1e4;currentConnectionIndex=0;candidates=null;visitedNodes=null;queuedNodes=null;activeCandidateStraightLineDistance;debug_lastNodeCostMap=new Map;maxCapacityFactor=1;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.centerNodeId=t.centerNodeId,this.sectionNodes=t.sectionNodes,this.sectionEdges=t.sectionEdges,this.sectionConnectionTerminals=t.sectionConnectionTerminals.map(t=>({...t,path:void 0})),this.nodeMap=t.nodeMap??new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=t.nodeEdgeMap??Fn(this.sectionEdges),this.colorMap=t.colorMap??{},this.usedNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,0])),this.totalNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,this.getTotalCapacity(t)]));const e=new Set(this.sectionNodes.map(t=>t.capacityMeshNodeId));this.currentSectionScore=Gl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:e}),t.hyperParameters?.SHUFFLE_SEED&&(this.sectionConnectionTerminals=Gn(this.sectionConnectionTerminals,t.hyperParameters?.SHUFFLE_SEED))}getTotalCapacity(t){return vh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){if(!this.nodeMap.has(t.capacityMeshNodeId))return 1/0;const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+e**2*4)*n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(e.push(n.node),!this.nodeMap.has(n.node.capacityMeshNodeId)){console.warn("Backtracked path went outside section bounds");break}n=n.prevCandidate}return e.reverse()}getNeighboringNodes(t){return this.nodeMap.has(t.capacityMeshNodeId)?this.nodeEdgeMap.get(t.capacityMeshNodeId)?.flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t)).filter(Boolean)??[]:[]}isConnectedToEndGoal(t,e){return!(!this.nodeMap.has(t.capacityMeshNodeId)||!this.nodeMap.has(e.capacityMeshNodeId))&&(this.nodeEdgeMap.get(t.capacityMeshNodeId)??[]).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}doesNodeHaveCapacityForTrace(t,e){return!0}reduceCapacityAlongPath(t){for(const e of t)if(this.usedNodeCapacityMap.has(e.capacityMeshNodeId)){const t=e.capacityMeshNodeId,n=this.nodeMap.get(t);if(!n){console.warn(`Node ${t} from path not found in section's nodeMap during score update.`);continue}const s=this.totalNodeCapacityMap.get(t),o=this.usedNodeCapacityMap.get(t)??0,i=Vl(o,s,n);this.currentSectionScore-=i;const r=o+1;this.usedNodeCapacityMap.set(t,r);const a=Vl(r,s,n);this.currentSectionScore+=a}}getSolvedSectionScore(){return this.currentSectionScore}_step(){const t=this.sectionConnectionTerminals[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const e=this.nodeMap.get(t.startNodeId),n=this.nodeMap.get(t.endNodeId);if(!e||!n)return console.error(`Start or end node not found in section for connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);this.candidates||this._setupAStar(e,n);const s=this.candidates;if(0===s.length)return void this._handleCandidatesExhausted(t);s.sort((t,e)=>t.f-e.f);const o=s.shift();if(s.length>this.MAX_CANDIDATES_IN_MEMORY&&s.splice(this.MAX_CANDIDATES_IN_MEMORY,s.length-this.MAX_CANDIDATES_IN_MEMORY),this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId)return void this._handleGoalReached(o,t,n);const i=this.getNeighboringNodes(o.node);for(const e of i){if(this.queuedNodes?.has(e.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(e,o.node))continue;if(e._containsObstacle){const n=e.capacityMeshNodeId===t.startNodeId,s=e.capacityMeshNodeId===t.endNodeId;if(!n&&!s)continue}const i=this.computeG(o,e,n),r=this.computeH(o,e,n),a=i+r*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(e.capacityMeshNodeId,{f:a,g:i,h:r});const c={prevCandidate:o,node:e,f:a,g:i,h:r};this.queuedNodes?.add(e.capacityMeshNodeId),s.push(c)}}computeProgress(){const t=this.sectionConnectionTerminals.length;if(0===t)return 1;let e=this.currentConnectionIndex/t;if(this.currentConnectionIndex<t&&this.candidates&&this.candidates.length>0&&this.activeCandidateStraightLineDistance&&this.activeCandidateStraightLineDistance>0){const n=this.candidates.reduce((t,e)=>e.f<t.f?e:t);e+=Math.max(0,Math.min(1,1-n.h/this.activeCandidateStraightLineDistance))/t}else this.solved&&(e=1);return Math.min(1,e)}_setupAStar(t,e){this.candidates=[{prevCandidate:null,node:t,f:0,g:0,h:0}],this.visitedNodes=new Set([t.capacityMeshNodeId]),this.debug_lastNodeCostMap=new Map,this.activeCandidateStraightLineDistance=k(t.center,e.center);const n=this.computeH(null,t,e);this.candidates[0].h=n,this.candidates[0].f=n*this.GREEDY_MULTIPLIER,this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:this.candidates[0].f,g:0,h:n}),this.queuedNodes=new Set([t.capacityMeshNodeId])}_handleCandidatesExhausted(t){console.error(`Ran out of candidates for section connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}_handleGoalReached(t,e,n){const s=this.getBacktrackedPath(t);e.path=s,this.reduceCapacityAlongPath(s),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}visualize(){const t=this.sectionConnectionTerminals.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connectionName,path:t.path})),e=Zl({sectionNodes:this.sectionNodes,sectionEdges:this.sectionEdges,sectionConnectionTerminals:this.sectionConnectionTerminals,completedPaths:t,nodeMap:this.nodeMap,colorMap:this.colorMap,centerNodeId:null,title:`Section Pathing: Conn ${this.currentConnectionIndex+1}/${this.sectionConnectionTerminals.length} (${this.sectionNodes.length} nodes)`,nodeOpacity:.1});for(const t of this.sectionNodes){const n=e.rects.findIndex(e=>e.label?.includes(t.capacityMeshNodeId));if(-1!==n){const s=this.debug_lastNodeCostMap.get(t.capacityMeshNodeId),o=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,i=this.getTotalCapacity(t),r=`${o.toFixed(1)}/${i.toFixed(1)}`,a=s?`f:${s.f.toFixed(1)} g:${s.g.toFixed(1)} h:${s.h.toFixed(1)}`:"cost:?";e.rects[n].label=[t.capacityMeshNodeId,`Cap: ${r}`,a,`Z: ${t.availableZ.join(",")}`].join("\n"),o>i&&(e.rects[n].stroke=In("red",.7))}}if(this.candidates&&this.candidates.length>0){const t=this.candidates.slice().sort((t,e)=>t.f-e.f).slice(0,5),n=this.sectionConnectionTerminals[this.currentConnectionIndex],s=n?.connectionName??"unknown",o=this.colorMap[s]??"purple";t.forEach((t,n)=>{const s=.8*(1-n/5),i=this.getBacktrackedPath(t);i.length>0&&e.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:In(o,1-s),strokeWidth:.05})})}return e}},Jl=t=>Array.from({length:t},(t,e)=>e),Kl=class extends is{getSolverName(){return"HyperCapacityPathingSingleSectionSolver"}constructorParams;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.constructorParams=t}computeG(t){return-t.getSolvedSectionScore()}computeH(t){return 0}getCombinationDefs(){const t=this.constructorParams.sectionConnectionTerminals.length;return 2===t?[["orderings2_for2"]]:3===t?[["orderings6_for3"]]:4===t?[["orderings24_for4"]]:[["orderings30"]]}getFailureMessage(){return`All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`}getHyperParameterDefs(){return[{name:"orderings2_for2",possibleValues:Jl(2).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings6_for3",possibleValues:Jl(6).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings24_for4",possibleValues:Jl(24).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings30",possibleValues:Jl(30).map(t=>({SHUFFLE_SEED:t}))}]}generateSolver(t){return new ql({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}onSolve({solver:t}){this.winningSolver=t}get centerNodeId(){return this.constructorParams.centerNodeId}get sectionNodes(){return this.constructorParams.sectionNodes}get sectionConnectionTerminals(){return this.winningSolver?.sectionConnectionTerminals}};import Ql from"object-hash";var td=t=>Math.floor(10*t)/10,ed=class extends Kl{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;sectionNodeIdSet;cachedSectionConnectionTerminals=null;sectionScore=0;constructor(t){t.nodeMap=t.nodeMap??new Map(t.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),super(t),this.sectionNodeIdSet=new Set(t.sectionNodes.map(t=>t.capacityMeshNodeId)),this.cacheProvider=void 0===t.cacheProvider?Me():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}_computeBfsOrderingOfNodesInSection(){const t=new Set(this.constructorParams.centerNodeId),e=[],n=[{ancestorCapacitySum:0,capacity:0,g:0,capacityMeshNodeId:this.constructorParams.centerNodeId}];for(;n.length>0;){n.sort((t,e)=>e.g-t.g);const s=n.pop();if(!s)break;e.push(s.capacityMeshNodeId);const o=this.constructorParams.nodeEdgeMap.get(s.capacityMeshNodeId).flatMap(t=>t.nodeIds).filter(e=>!t.has(e)).filter(t=>this.sectionNodeIdSet.has(t));for(const e of o){t.add(e);const o=this.constructorParams.nodeMap.get(e),i=vh(o);n.push({ancestorCapacitySum:s.g,capacity:i,g:s.g+i,capacityMeshNodeId:e})}}return e}computeCacheKeyAndTransform(){const t=this._computeBfsOrderingOfNodesInSection(),e=new Map,n=new Map;t.forEach((t,s)=>{const o=`node${s}`;e.set(t,o),n.set(o,t)});const s={};for(const n of t){const t=e.get(n),o=this.constructorParams.nodeMap.get(n),i=vh(o);s[t]=td(i).toFixed(1)}const o=new Set,i=[];for(const n of t){const t=e.get(n),s=this.constructorParams.nodeEdgeMap.get(n)??[];for(const r of s){const s=r.nodeIds.find(t=>t!==n);if(this.sectionNodeIdSet.has(s)){const n=[t,e.get(s)].sort(),r=`${n[0]}-${n[1]}`;o.has(r)||(i.push(n),o.add(r))}}}i.sort((t,e)=>t[0]!==e[0]?t[0].localeCompare(e[0]):t[1].localeCompare(e[1]));const r={},a=new Map,c=new Map;for(const t of this.constructorParams.sectionConnectionTerminals){const n=e.get(t.startNodeId),s=e.get(t.endNodeId),[o,i]=[n,s].sort(),h=`${o}->${i}`,l=c.get(h)??0;c.set(h,l+1);const d=`${o}->${i}::${l}`;r[d]={start:o,end:i},a.set(d,t.connectionName)}const h=`capacitypathing:${Ql({node_capacity_map:s,node_edge_map:i,terminals:r})}`,l={cacheSpaceToRealConnectionId:a,cacheSpaceToRealNodeId:n};return this.cacheKey=h,this.cacheToSolveSpaceTransform=l,{cacheKey:h,cacheToSolveSpaceTransform:l}}applyCachedSolution(t){if(!this.cacheToSolveSpaceTransform)return console.error("Cache transform not available, cannot apply cached solution."),void(this.failed=!0);if(!t.success)return this.failed=!0,void(this.cacheHit=!0);this.cachedSectionConnectionTerminals=[];const{cacheSpaceToRealNodeId:e,cacheSpaceToRealConnectionId:n}=this.cacheToSolveSpaceTransform;for(const[s,o]of Object.entries(t.solutionPaths)){const t=n.get(s);if(!t){console.warn(`Could not find real connection name for ${s}`);continue}const i=this.constructorParams.sectionConnectionTerminals.find(e=>e.connectionName===t);if(!i){console.warn(`Could not find original terminal for connection name ${t}`);continue}const r=o.map(n=>{const s=e.get(n);if(!s)throw new Error(`Could not map cache node ID ${n} to real node ID for connection ${t}`);const o=this.constructorParams.nodeMap.get(s);if(!o)throw new Error(`Could not find node with ID ${s} in nodeMap for connection ${t}`);return o});this.cachedSectionConnectionTerminals.push({...i,path:r})}this.sectionScore=t.sectionScore,this.solved=!0,this.cacheHit=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheKey)return void console.error("Cannot save to cache without cache key.");if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available, cannot save solution to cache.");let t;if(this.failed)t={success:!1};else{if(!this.solved)return;{const e={},{cacheSpaceToRealNodeId:n,cacheSpaceToRealConnectionId:s}=this.cacheToSolveSpaceTransform,o=new Map;for(const[t,e]of n)o.set(e,t);const i=new Map;for(const[t,e]of s)i.set(e,t);const r=[];if(super.sectionConnectionTerminals)for(const t of super.sectionConnectionTerminals)if(t.path&&t.path.length>0){const e=t.path.map(t=>t.capacityMeshNodeId);r.push([t.connectionName,e])}for(const[t,n]of r){const s=i.get(t);if(!s){console.warn(`Could not find cache space connection ID for ${t} when saving to cache.`);continue}const r=n.map(e=>{const n=o.get(e);if(!n)throw new Error(`Could not map real node ID ${e} to cache node ID for connection ${t} when saving to cache.`);return n});e[s]=r}t={success:!0,sectionScore:this.sectionScore,solutionPaths:e}}}try{this.cacheProvider?.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}get sectionConnectionTerminals(){return this.cacheHit&&this.solved&&this.cachedSectionConnectionTerminals?(console.log("returning the cached section connection terminals"),this.cachedSectionConnectionTerminals):super.sectionConnectionTerminals}visualize(){if(!this.cacheHit)return super.visualize();return Zl({sectionNodes:this.constructorParams.sectionNodes,sectionEdges:this.constructorParams.sectionEdges,sectionConnectionTerminals:this.cachedSectionConnectionTerminals,completedPaths:this.cachedSectionConnectionTerminals.map(t=>({connectionName:t.connectionName,path:t.path})),nodeMap:this.constructorParams.nodeMap,colorMap:this.constructorParams.colorMap,title:"CachedHyperCapacityPathingSingleSectionSolver"})}},nd=class extends Ln{getSolverName(){return"CapacityPathingMultiSectionSolver"}simpleRouteJson;nodes;edges;nodeEdgeMap;connectionsWithNodes=[];colorMap;initialSolver;cacheProvider;stage="initialization";nodeMap=new Map;allNodeIdsSet;usedNodeCapacityMap=new Map;totalNodeCapacityMap=new Map;nodeCapacityPercentMap=new Map;nodeOptimizationAttemptCountMap=new Map;currentSection=null;sectionSolver=null;currentScheduleIndex=0;stats;OPTIMIZATION_SCHEDULE=[{MAX_ATTEMPTS_PER_NODE:1,MAX_EXPANSION_DEGREES:3,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.05},{MAX_ATTEMPTS_PER_NODE:2,MAX_EXPANSION_DEGREES:5,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.2},{MAX_ATTEMPTS_PER_NODE:3,MAX_EXPANSION_DEGREES:7,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.9}];get currentSchedule(){return this.OPTIMIZATION_SCHEDULE[this.currentScheduleIndex]??null}constructor(t){super(),this.stats={successfulOptimizations:0,failedOptimizations:0,failedSectionSolvers:0,startingScore:0,scheduleScores:this.OPTIMIZATION_SCHEDULE.map(({MAX_EXPANSION_DEGREES:t})=>({maxExpansionDegrees:t,endingScore:0,endingHighestNodePf:0,sectionAttempts:0})),cacheHits:0,cacheMisses:0},this.MAX_ITERATIONS=t.MAX_ITERATIONS??1e7,this.cacheProvider=t.cacheProvider,this.simpleRouteJson=t.simpleRouteJson,this.nodes=t.nodes,this.edges=t.edges,this.nodeEdgeMap=Fn(this.edges),this.colorMap=t.colorMap??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges),this.initialSolver=t.initialPathingSolver||new jl({simpleRouteJson:this.simpleRouteJson,nodes:this.nodes,edges:this.edges,colorMap:this.colorMap}),this.activeSubSolver=this.initialSolver;for(const t of this.nodes){const e=this.initialSolver.getTotalCapacity(t);this.totalNodeCapacityMap.set(t.capacityMeshNodeId,e)}this.allNodeIdsSet=new Set(this.nodes.map(t=>t.capacityMeshNodeId))}_stepInitialization(){if(this.initialSolver?.step(),this.initialSolver?.failed)return this.failed=!0,void(this.error=this.initialSolver.error);if(this.initialSolver?.solved){this.usedNodeCapacityMap=new Map(this.initialSolver.usedNodeCapacityMap);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s),this.nodeOptimizationAttemptCountMap.set(t.capacityMeshNodeId,0)}this.connectionsWithNodes=this.initialSolver.connectionsWithNodes,this.stats.startingScore=Gl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet}),this.stage="section-optimization"}}_getNextNodeToOptimize(){let t=0,e=0,n=null;for(const s of this.nodes){if(s._containsTarget)continue;const o=this.nodeOptimizationAttemptCountMap.get(s.capacityMeshNodeId),i=this.totalNodeCapacityMap.get(s.capacityMeshNodeId),r=Ul({usedCapacity:this.usedNodeCapacityMap.get(s.capacityMeshNodeId)??0,totalCapacity:i,layerCount:s.availableZ.length}),a=r/(o+1);o<this.currentSchedule.MAX_ATTEMPTS_PER_NODE&&a>t&&r>this.currentSchedule.MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE&&(t=a,e=r,n=s.capacityMeshNodeId)}return n}getOverallScore(){let t=0;for(const e of this.nodes){if(e._containsTarget)continue;const n=this.totalNodeCapacityMap.get(e.capacityMeshNodeId),s=Ul({usedCapacity:this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,totalCapacity:n,layerCount:e.availableZ.length});s>t&&(t=s)}return{highestNodePf:t,score:Gl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet})}}_stepSectionOptimization(){if(!this.sectionSolver){const t=this._getNextNodeToOptimize();if(!t){const{highestNodePf:t,score:e}=this.getOverallScore();return this.stats.scheduleScores[this.currentScheduleIndex].endingHighestNodePf=t,this.stats.scheduleScores[this.currentScheduleIndex].endingScore=e,this.currentScheduleIndex++,void(this.currentSchedule||(this.solved=!0))}const e=(t=>{const{centerNodeId:e,connectionsWithNodes:n,nodeMap:s,edges:o,nodeEdgeMap:i,expansionDegrees:r}=t,a=new Set,c=[{nodeId:e,depth:0}];a.add(e);let h=0;for(;h<c.length;){const{nodeId:t,depth:e}=c[h++];if(e>=r)continue;const n=i.get(t)?.flatMap(e=>e.nodeIds.filter(e=>e!==t))??[];for(const t of n)a.has(t)||(a.add(t),c.push({nodeId:t,depth:e+1}))}const l=Array.from(a).map(t=>s.get(t)),d=o.filter(t=>{const[e,n]=t.nodeIds;return a.has(e)&&a.has(n)}),u=[];for(const t of n){if(!t.path)continue;let e=null,n=null;for(const n of t.path)if(a.has(n.capacityMeshNodeId)){e=n.capacityMeshNodeId;break}for(let e=t.path.length-1;e>=0;e--){const s=t.path[e];if(a.has(s.capacityMeshNodeId)){n=s.capacityMeshNodeId;break}}e&&n&&u.push({connectionName:t.connection.name,startNodeId:e,endNodeId:n})}return{sectionConnectionTerminals:u,sectionNodes:l,sectionEdges:d,centerNodeId:e}})({centerNodeId:t,connectionsWithNodes:this.connectionsWithNodes,nodeMap:this.nodeMap,edges:this.edges,expansionDegrees:this.currentSchedule.MAX_EXPANSION_DEGREES,nodeEdgeMap:this.nodeEdgeMap});this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++,this.currentSection=e,this.sectionSolver=new ed({sectionNodes:this.currentSection.sectionNodes,sectionEdges:this.currentSection.sectionEdges,sectionConnectionTerminals:this.currentSection.sectionConnectionTerminals,colorMap:this.colorMap,centerNodeId:this.currentSection.centerNodeId,nodeEdgeMap:this.nodeEdgeMap,hyperParameters:{EXPANSION_DEGREES:this.currentSchedule.MAX_EXPANSION_DEGREES},cacheProvider:this.cacheProvider}),this.activeSubSolver=this.sectionSolver,this.nodeOptimizationAttemptCountMap.set(t,(this.nodeOptimizationAttemptCountMap.get(t)??0)+1)}if(this.sectionSolver.step(),(this.sectionSolver.failed||this.sectionSolver.solved)&&(this.sectionSolver.cacheHit?this.stats.cacheHits++:this.stats.cacheMisses++),this.sectionSolver.failed)return console.warn(`Section solver failed for node ${this.currentSection.centerNodeId}. Error: ${this.sectionSolver.error}`),this.stats.failedSectionSolvers++,this.stats.failedOptimizations++,this.sectionSolver=null,void(this.activeSubSolver=null);if(this.sectionSolver.solved){const t=this.sectionSolver.sectionConnectionTerminals,e=this.sectionSolver.sectionNodes,n=this.sectionSolver.centerNodeId;if(this.sectionSolver=null,this.activeSubSolver=null,!t)return void console.warn(`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`);const s=new Set(e.map(t=>t.capacityMeshNodeId)),o=Gl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:s}),i=new Map(this.usedNodeCapacityMap),r=t;for(const t of r){const e=this.connectionsWithNodes.find(e=>e.connection.name===t.connectionName);if(e?.path)for(const t of e.path)if(s.has(t.capacityMeshNodeId)){const e=i.get(t.capacityMeshNodeId)??0;i.set(t.capacityMeshNodeId,Math.max(0,e-1))}}for(const t of r)if(t.path)for(const e of t.path)s.has(e.capacityMeshNodeId)&&i.set(e.capacityMeshNodeId,(i.get(e.capacityMeshNodeId)??0)+1);Gl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:i,nodeMap:this.nodeMap,sectionNodeIds:s})>o?(this.stats.successfulOptimizations++,this._mergeSolvedSectionPaths({centerNodeId:n,sectionConnectionTerminals:t}),this._recalculateNodeCapacityUsage()):this.stats.failedOptimizations++}}_mergeSolvedSectionPaths({centerNodeId:t,sectionConnectionTerminals:e}){for(const n of e){if(!n.path){console.warn(`No path found for connection ${n.connectionName} in section ${t}`);continue}const e=this.connectionsWithNodes.find(t=>t.connection.name===n.connectionName);if(!e||!e.path){console.warn(`Original connection or path not found for ${n.connectionName} while merging section ${t}`);continue}const s=e.path,o=n.path,i=s.findIndex(t=>t.capacityMeshNodeId===n.startNodeId),r=s.findIndex(t=>t.capacityMeshNodeId===n.endNodeId);if(-1===i||-1===r){console.warn(`Could not find start/end nodes (${n.startNodeId}/${n.endNodeId}) in original path for ${n.connectionName}`);continue}const[a,c]=i<=r?[i,r]:[r,i],h=s.slice(0,a),l=s.slice(c+1);let d=o;if(o.length>0&&s[a]&&o[0].capacityMeshNodeId!==s[a].capacityMeshNodeId){if(o[o.length-1].capacityMeshNodeId!==s[a].capacityMeshNodeId){console.warn(`New section path for ${n.connectionName} doesn't align with original path boundaries. Skipping merge for this connection.`);continue}d=[...o].reverse()}e.path=[...h,...d,...l]}}_recalculateNodeCapacityUsage(){this.usedNodeCapacityMap.clear();for(const t of this.connectionsWithNodes)if(t.path)for(const e of t.path)this.usedNodeCapacityMap.set(e.capacityMeshNodeId,(this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0)+1);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s)}}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}_step(){this.iterations>=this.MAX_ITERATIONS-1?this.solved=!0:"initialization"===this.stage?this._stepInitialization():"section-optimization"===this.stage&&this._stepSectionOptimization()}visualize(){const t=this.connectionsWithNodes.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connection.name,path:t.path}));return Zl({nodeMap:this.nodeMap,sectionConnectionTerminals:this.connectionsWithNodes.map(t=>({connectionName:t.connection.name,startNodeId:t.path?.[0]?.capacityMeshNodeId,endNodeId:t.path?.[t.path.length-1]?.capacityMeshNodeId})),completedPaths:t,sectionNodes:this.nodes,sectionEdges:this.edges,colorMap:this.colorMap,totalCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeOpacity:.05,title:"Capacity Pathing Multi-Section Solver (Solved)"})}},sd=class extends Ln{getSolverName(){return"DeadEndSolver"}removedNodeIds;targetNodeIds;leaves;leavesIndex;adjacencyList;nodeMap;nodes;edges;constructor({nodes:t,edges:e}){super(),this.MAX_ITERATIONS=t.length,this.nodes=t,this.edges=e,this.removedNodeIds=new Set,this.targetNodeIds=new Set(t.filter(t=>t._containsTarget).map(t=>t.capacityMeshNodeId)),this.adjacencyList=new Map(t.map(({capacityMeshNodeId:t})=>[t,new Set]));for(const{nodeIds:[t,n]}of e)this.adjacencyList.get(t).add(n),this.adjacencyList.get(n).add(t);this.leavesIndex=0,this.leaves=[...this.adjacencyList.entries()].filter(([t,e])=>1===e.size).filter(([t,e])=>!this.targetNodeIds.has(t)).map(([t,e])=>t)}_step(){if(this.leavesIndex===this.leaves.length)return void(this.solved=!0);const t=this.leaves[this.leavesIndex],e=this.adjacencyList.get(t);if(!e||0===e.size)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));const[n]=e,s=n?this.adjacencyList.get(n):void 0;if(!n||!s)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));s.delete(t),this.removedNodeIds.add(t),this.adjacencyList.delete(t),1!==s.size||this.targetNodeIds.has(n)||this.leaves.push(n),this.leavesIndex+=1,this.leavesIndex===this.leaves.length&&(this.solved=!0)}visualize(){if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const o=Math.min(...n.availableZ),i=Math.min(...s.availableZ),r={x:n.center.x+o*n.width*.05,y:n.center.y-o*n.width*.05},a={x:s.center.x+i*s.width*.05,y:s.center.y-i*s.width*.05},c=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${c.join(",")}`,points:[r,a],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5",strokeColor:t.nodeIds.some(t=>this.removedNodeIds.has(t))?In("black",.9):void 0})}}return e}},od=class extends Qh{getSolverName(){return"NoOffBoardMultipleHighDensityRouteStitchSolver"}constructor(t){super(t),this.unsolvedRoutes=[];const e=new Map;for(const n of t.hdRoutes){const t=e.get(n.connectionName)||[];t.push(n),e.set(n.connectionName,t)}for(const[n,s]of e.entries()){const e=t.connections.find(t=>t.name===n);if(!e)continue;const o={...e.pointsToConnect[0],z:Rn(Tn(e.pointsToConnect[0]),t.layerCount)},i={...e.pointsToConnect[1],z:Rn(Tn(e.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:n,hdRoutes:s,start:o,end:i})}for(const n of t.connections)e.has(n.name)||this.unsolvedRoutes.push({connectionName:n.name,hdRoutes:[],start:{...n.pointsToConnect[0],z:Rn(Tn(n.pointsToConnect[0]),t.layerCount)},end:{...n.pointsToConnect[1],z:Rn(Tn(n.pointsToConnect[1]),t.layerCount)}})}},id=.005,rd=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]);e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new $n(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){return this.getAdjacentSameLayerUnprocessedNodes2(t)}getAdjacentSameLayerUnprocessedNodes2(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<id&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<id&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<id&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<id&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Same Layer Node Merger"};for(const e of this.newNodes)t.rects.push(kl(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=kl(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=kl(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},ad=class extends Ln{getSolverName(){return"StrawSolver"}multiLayerNodes;strawNodes;skippedNodes;unprocessedNodes;strawSize;nodeIdCounter;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.strawSize=t.strawSize??.5,this.multiLayerNodes=[],this.strawNodes=[],this.skippedNodes=[],this.nodeIdCounter=0,this.unprocessedNodes=[];for(const e of t.nodes)1===e.availableZ.length?this.unprocessedNodes.push(e):this.multiLayerNodes.push(e)}getCapacityOfMultiLayerNodesWithinBounds(t){let e=0;for(const n of this.multiLayerNodes){const s=n.center.x-n.width/2,o=n.center.x+n.width/2,i=n.center.y-n.height/2,r=n.center.y+n.height/2,a=Math.max(t.minX,s),c=Math.min(t.maxX,o),h=Math.max(t.minY,i),l=Math.min(t.maxY,r);if(a<c&&h<l){const t=(c-a)*(l-h)/(n.width*n.height);e+=vh(n)*t}}return e}getSurroundingCapacities(t){const e=Math.min(t.width,t.height);return{leftSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2-e,maxX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),rightSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x+t.width/2,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),topSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2-e,maxY:t.center.y-t.height/2}),bottomSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y+t.height/2,maxY:t.center.y+t.height/2+e})}}createStrawsForNode(t){const e=[],{leftSurroundingCapacity:n,rightSurroundingCapacity:s,topSurroundingCapacity:o,bottomSurroundingCapacity:i}=this.getSurroundingCapacities(t);if(1*(n+s)>o+i){const n=Math.floor(t.height/this.strawSize),s=t.height/n;for(let o=0;o<n;o++){const n=t.center.y-t.height/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:t.center.x,y:n},width:t.width,height:s,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}else{const n=Math.floor(t.width/this.strawSize),s=t.width/n;for(let o=0;o<n;o++){const n=t.center.x-t.width/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:n,y:t.center.y},width:s,height:t.height,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}return e}getResultNodes(){return[...this.multiLayerNodes,...this.strawNodes,...this.skippedNodes]}_step(){const t=this.unprocessedNodes.pop();if(!t)return void(this.solved=!0);if(t.width<this.strawSize&&t.height<this.strawSize)return void this.skippedNodes.push(t);if(t._containsTarget)return void this.skippedNodes.push(t);const e=this.createStrawsForNode(t);this.strawNodes.push(...e),0===e.length&&this.strawNodes.push(t)}visualize(){const t={rects:[],lines:[],points:[],circles:[],title:"Straw Solver"};for(const e of this.unprocessedNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(200, 200, 200, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nUnprocessed\n${e.width}x${e.height}`});for(const e of this.strawNodes){const n=0===e.availableZ[0]?"rgba(0, 150, 255, 0.5)":"rgba(255, 100, 0, 0.5)";t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nLayer: ${e.availableZ[0]}\n${e.width}x${e.height}`,layer:`z${e.availableZ.join(",")}`})}for(const e of this.multiLayerNodes)t.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,fill:"rgba(100, 255, 100, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",layer:`z${e.availableZ.join(",")}`,label:`${e.capacityMeshNodeId}\nLayers: ${e.availableZ.join(",")}\n${e.width}x${e.height}`});return t}};function cd(t){const{nodeId:e,nodeIdToSegmentIds:n,segmentIdToNodeIds:s,hops:o}=t;if(0===o)return[e];const i=new Set([e]),r=[{nodeId:e,remainingHops:o}];for(;r.length>0;){const{nodeId:t,remainingHops:e}=r.shift();if(0===e)continue;const o=n.get(t)||[];for(const t of o){const n=s.get(t)||[];for(const t of n)i.has(t)||(i.add(t),r.push({nodeId:t,remainingHops:e-1}))}}return Array.from(i)}var hd=t=>Array.from(t.entries()).map(([t,{x:e,y:n,z:s}])=>`${t}(${e?.toFixed(3)??""},${n?.toFixed(3)??""},${s??""})`).sort().join("&"),ld=(t,e,n,s)=>{const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s);return o<=Math.max(n,s)&&i>=r},dd=(t,e,n,s)=>{const o=[],i=new Map(t.originalPointMap);for(const[t,e]of n.entries()){const n=i.get(t);i.set(t,{x:e.x??n.x,y:e.y??n.y,z:e.z??n.z})}for(const n of t.allNodeIds){if(!e.get(n))continue;const r=t.segmentPairsInNode.get(n);for(const t of r){const e=i.get(t[0]),s=i.get(t[1]);e.z!==s.z&&o.push({type:"transition_via",segmentPoints:t,capacityMeshNodeId:n,probabilityOfFailure:0})}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){if(s?.areIdsConnected(r[t][0],r[t][1]))continue;const a=r[t],c=r[e],h=i.get(a[0]),l=i.get(a[1]),d=i.get(c[0]),u=i.get(c[1]);if(!ld(h.z,l.z,d.z,u.z))continue;const p=L(h,l,d,u),f=h.z===l.z&&d.z===u.z&&h.z===d.z;p&&(f?o.push({type:"same_layer_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}):h.z===l.z&&d.z!==u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:a,transitionCrossingLine:c,probabilityOfFailure:0}):h.z!==l.z&&d.z===u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:c,transitionCrossingLine:a,probabilityOfFailure:0}):h.z!==l.z&&d.z!==u.z&&o.push({type:"double_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}))}}return o},ud=(t,e,n)=>{if("change_layer"===e.type)for(const n of e.segmentPointIds){const s=t.get(n)||{};t.set(n,{...s,z:e.newZ})}else if("swap_position_on_segment"===e.type){const[s,o]=e.segmentPointIds,i=n(s),r=n(o),a=t.get(s)||{},c=t.get(o)||{};t.set(s,{...a,x:r.x,y:r.y}),t.set(o,{...c,x:i.x,y:i.y})}else if("combined"===e.type)for(const s of e.operations)ud(t,s,n)},pd=(t,e)=>{const n=new Map,s=new Map,o=new Map,i=[];let r=0;for(const a of t)for(const t of a.assignedPoints){const c={segmentPointId:"SP"+r++,segmentId:a.nodePortSegmentId,capacityMeshNodeIds:e.get(a.nodePortSegmentId),connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,x:t.point.x,y:t.point.y,z:t.point.z,directlyConnectedSegmentPointIds:[]};n.set(c.segmentPointId,c);for(const t of c.capacityMeshNodeIds)s.set(t,[...s.get(t)??[],c.segmentPointId]);o.set(a.nodePortSegmentId,[...o.get(a.nodePortSegmentId)??[],c.segmentPointId]),i.push(c)}return{segmentPointMap:n,nodeToSegmentPointMap:s,segmentToSegmentPointMap:o}},fd=class extends Ln{getSolverName(){return"UnravelSectionSolver"}nodeMap;dedupedSegments;dedupedSegmentMap;MUTABLE_HOPS=1;unravelSection;candidates=[];lastProcessedCandidate=null;bestCandidate=null;originalCandidate;rootNodeId;nodeIdToSegmentIds;segmentIdToNodeIds;colorMap;tunedNodeCapacityMap;MAX_CANDIDATES=500;iterationsSinceImprovement=0;hyperParameters;selectedCandidateIndex=null;queuedOrExploredCandidatePointModificationHashes=new Set;constructorParams;constructor(t){if(super(),this.constructorParams=t,this.MUTABLE_HOPS=t.MUTABLE_HOPS??this.MUTABLE_HOPS,this.MAX_ITERATIONS=5e4,this.hyperParameters={...t.hyperParameters,MAX_ITERATIONS_WITHOUT_IMPROVEMENT:200},this.nodeMap=t.nodeMap,this.dedupedSegments=t.dedupedSegments,t.dedupedSegmentMap)this.dedupedSegmentMap=t.dedupedSegmentMap;else{this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t)}this.nodeIdToSegmentIds=t.nodeIdToSegmentIds,this.segmentIdToNodeIds=t.segmentIdToNodeIds,this.rootNodeId=t.rootNodeId,this.colorMap=t.colorMap??{},this.unravelSection=this.createUnravelSection({segmentPointMap:t.segmentPointMap,nodeToSegmentPointMap:t.nodeToSegmentPointMap,segmentToSegmentPointMap:t.segmentToSegmentPointMap}),this.tunedNodeCapacityMap=new Map;for(const t of this.unravelSection.allNodeIds)this.tunedNodeCapacityMap.set(t,vh(this.nodeMap.get(t)));this.originalCandidate=this.createInitialCandidate(),this.candidates=[this.originalCandidate]}getConstructorParams(){return{...this.constructorParams,segmentPointMap:this.unravelSection.segmentPointMap,nodeToSegmentPointMap:this.unravelSection.segmentPointsInNode,segmentToSegmentPointMap:this.unravelSection.segmentPointsInSegment}}createUnravelSection(t){const e=cd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS}),n=cd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS+1}),s=Array.from(new Set(n).difference(new Set(e)));t?.segmentPointMap||(t=pd(this.dedupedSegments,this.segmentIdToNodeIds));const o=new Map;for(const e of n)o.set(e,t.nodeToSegmentPointMap.get(e));const i=new Map;for(const e of n)for(const n of o.get(e)){const e=t.segmentPointMap.get(n);i.set(n,e)}const r=Array.from(i.values()),a=new Map;for(const t of r)a.set(t.segmentId,[...a.get(t.segmentId)??[],t.segmentPointId]);for(const[e,n]of o.entries())for(let e=0;e<n.length;e++){const s=t.segmentPointMap.get(n[e]);for(let o=e+1;o<n.length;o++){const e=t.segmentPointMap.get(n[o]);e.segmentPointId!==s.segmentPointId&&(e.segmentId!==s.segmentId&&e.connectionName===s.connectionName&&(e.directlyConnectedSegmentPointIds.includes(s.segmentPointId)||(s.directlyConnectedSegmentPointIds.push(e.segmentPointId),e.directlyConnectedSegmentPointIds.push(s.segmentPointId))))}}const c=new Map;for(const t of n)c.set(t,[]);for(const e of r)for(const n of e.capacityMeshNodeIds){const s=c.get(n);if(s)for(const o of e.directlyConnectedSegmentPointIds){const i=t.segmentPointMap.get(o);i.segmentPointId!==e.segmentPointId&&(i.capacityMeshNodeIds.some(t=>t===n)&&(s.some(([t,n])=>t===e.segmentPointId&&n===i.segmentPointId||t===i.segmentPointId&&n===e.segmentPointId)||s.push([e.segmentPointId,i.segmentPointId])))}}const h=new Set;for(const t of e)for(const e of this.nodeIdToSegmentIds.get(t)){this.segmentIdToNodeIds.get(e).every(t=>!this.nodeMap.get(t)._containsTarget)&&h.add(e)}const l=new Set;for(const t of r){const n=t.capacityMeshNodeIds.some(t=>e.includes(t)),s=this.dedupedSegmentMap.get(t.segmentId),o=s&&s.availableZ.length>1;(n||o)&&l.add(t.segmentPointId)}const d=new Set;for(const t of r){if(t.capacityMeshNodeIds.some(t=>this.nodeMap.get(t)?._containsTarget)){const e=this.dedupedSegmentMap.get(t.segmentId);e&&1===e.availableZ.length&&d.add(t.segmentPointId)}}return{allNodeIds:n,mutableNodeIds:e,immutableNodeIds:s,mutableSegmentIds:h,segmentPairsInNode:c,segmentPointMap:i,segmentPointsInNode:o,segmentPointsInSegment:a,originalPointMap:i,mutableSegmentPointIds:l,zLockedSegmentPointIds:d}}createInitialCandidate(){const t=new Map,e=dd(this.unravelSection,this.nodeMap,t),n=this.computeG({issues:e,originalCandidate:{},operationsPerformed:0,operation:{}});return{pointModifications:t,g:n,h:0,f:n,operationsPerformed:0,candidateHash:hd(t),issues:dd(this.unravelSection,this.nodeMap,t)}}get nextCandidate(){return this.candidates[0]??null}getPointInCandidate(t,e){const n=this.unravelSection.segmentPointMap.get(e),s=t.pointModifications.get(e);return{x:s?.x??n.x,y:s?.y??n.y,z:s?.z??n.z,segmentId:n.segmentId}}getConnectionSegmentPointIds(t){const e=[];for(const[n,s]of this.unravelSection.segmentPointMap.entries())s.connectionName===t&&e.push(n);return e}canConnectionUseLayer(t,e){for(const n of t){const t=this.unravelSection.segmentPointMap.get(n),s=this.dedupedSegmentMap.get(t.segmentId);if(!s||!s.availableZ.includes(e))return!1}return!0}getOperationsForIssue(t,e){const n=[];if("transition_via"===e.type){const[s,o]=e.segmentPoints,i=this.getPointInCandidate(t,s),r=this.getPointInCandidate(t,o),a=this.unravelSection.segmentPointMap.get(s),c=(this.unravelSection.segmentPointMap.get(o),this.dedupedSegmentMap.get(i.segmentId).availableZ),h=this.dedupedSegmentMap.get(r.segmentId).availableZ,l=this.unravelSection.zLockedSegmentPointIds.has(s),d=this.unravelSection.zLockedSegmentPointIds.has(o),u=this.getConnectionSegmentPointIds(a.connectionName);if(this.canConnectionUseLayer(u,r.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:t})}if(this.canConnectionUseLayer(u,i.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:t})}this.unravelSection.mutableSegmentPointIds.has(s)&&!l&&c.includes(r.z)&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:[s]}),this.unravelSection.mutableSegmentPointIds.has(o)&&!d&&h.includes(i.z)&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:[o]})}if("same_layer_crossing"===e.type){const[t,s]=e.crossingLine1,[o,i]=e.crossingLine2,r=[],a=this.unravelSection.segmentPointMap.get(t),c=this.unravelSection.segmentPointMap.get(s),h=this.unravelSection.segmentPointMap.get(o),l=this.unravelSection.segmentPointMap.get(i),d=this.unravelSection.mutableSegmentPointIds.has(t),u=this.unravelSection.mutableSegmentPointIds.has(s),p=this.unravelSection.mutableSegmentPointIds.has(o),f=this.unravelSection.mutableSegmentPointIds.has(i),m=this.unravelSection.zLockedSegmentPointIds.has(t),g=this.unravelSection.zLockedSegmentPointIds.has(s),y=this.unravelSection.zLockedSegmentPointIds.has(o),x=this.unravelSection.zLockedSegmentPointIds.has(i);d&&p&&a.segmentId===h.segmentId&&r.push([t,o]),d&&f&&a.segmentId===l.segmentId&&r.push([t,i]),u&&p&&c.segmentId===h.segmentId&&r.push([s,o]),u&&f&&c.segmentId===l.segmentId&&r.push([s,i]);for(const[t,e]of r)n.push({type:"swap_position_on_segment",segmentPointIds:[t,e]});const v=this.getConnectionSegmentPointIds(a.connectionName),b=this.getConnectionSegmentPointIds(h.connectionName),P=new Set;for(const t of this.unravelSection.segmentPointMap.values()){const e=this.dedupedSegmentMap.get(t.segmentId);if(e)for(const t of e.availableZ)P.add(t)}for(const t of P)if(t!==a.z&&this.canConnectionUseLayer(v,t)){const e=v.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}for(const t of P)if(t!==h.z&&this.canConnectionUseLayer(b,t)){const e=b.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}const S=this.dedupedSegmentMap.get(a.segmentId),M=this.dedupedSegmentMap.get(c.segmentId),N=this.dedupedSegmentMap.get(h.segmentId),I=this.dedupedSegmentMap.get(l.segmentId),_=(t,e)=>t.every(t=>t.availableZ.includes(e));if(d&&u&&!m&&!g){const e=0===a.z?1:0;_([S,M],e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t,s]})}if(p&&f&&!y&&!x){const t=0===h.z?1:0;_([N,I],t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o,i]})}if(d&&!m){const e=0===a.z?1:0;S.availableZ.includes(e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t]})}if(u&&!g){const t=0===c.z?1:0;M.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[s]})}if(p&&!y){const t=0===h.z?1:0;N.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o]})}if(f&&!x){const t=0===l.z?1:0;I.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i]})}}return n}computeG(t){const{issues:e,originalCandidate:n,operationsPerformed:s,operation:o}=t,i=new Map;for(const t of e){i.has(t.capacityMeshNodeId)||i.set(t.capacityMeshNodeId,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0});const e=i.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"===t.type||"single_transition_crossing"===t.type?e.numEntryExitLayerChanges++:t.type}let r=0;for(const[t,{numEntryExitLayerChanges:e,numSameLayerCrossings:n,numTransitionCrossings:s}]of i){const o=this.nodeMap.get(t),i=Math.min(Ph(o,n,e,s),.999999);r+=Math.log(1-i)}var a;return(a=r)<-Math.LN2?Math.log(1-Math.exp(a)):Math.log(-Math.expm1(a))}getUnexploredNeighborByApplyingOperation(t,e){const n=new Map(t.pointModifications);ud(n,e,e=>this.getPointInCandidate(t,e));const s=hd(n);if(this.queuedOrExploredCandidatePointModificationHashes.has(s))return null;const o=dd(this.unravelSection,this.nodeMap,n),i=t.operationsPerformed+1,r=this.computeG({issues:o,originalCandidate:t,operationsPerformed:i,operation:e});return{issues:o,g:r,h:0,f:r,pointModifications:n,candidateHash:s,operationsPerformed:i}}getNeighborOperationsForCandidate(t){return t.issues.flatMap(e=>this.getOperationsForIssue(t,e))}getNeighbors(t){const e=[],n=this.getNeighborOperationsForCandidate(t);for(const s of n){const n=this.getUnexploredNeighborByApplyingOperation(t,s);n&&e.push(n)}return e}_step(){const t=this.candidates.shift();this.iterationsSinceImprovement++,this.iterationsSinceImprovement>this.hyperParameters.MAX_ITERATIONS_WITHOUT_IMPROVEMENT?this.solved=!0:t?(this.lastProcessedCandidate=t,t.f<(this.bestCandidate?.f??1/0)&&(this.bestCandidate=t,this.iterationsSinceImprovement=0),this.getNeighbors(t).forEach(t=>{this.queuedOrExploredCandidatePointModificationHashes.has(t.candidateHash)||(this.queuedOrExploredCandidatePointModificationHashes.add(t.candidateHash),this.candidates.push(t))}),this.candidates.sort((t,e)=>t.f-e.f),this.candidates.length=Math.min(this.candidates.length,this.MAX_CANDIDATES)):this.solved=!0}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Section Solver"};let e=null;if(e=null!==this.selectedCandidateIndex?"best"===this.selectedCandidateIndex?this.bestCandidate:"original"===this.selectedCandidateIndex?this.originalCandidate:this.candidates[this.selectedCandidateIndex]:this.solved?this.bestCandidate:this.lastProcessedCandidate||this.candidates[0],!e)return t;const n=new Map;for(const[t,s]of this.unravelSection.segmentPointMap){const o={...s},i=e.pointModifications.get(t);i&&(void 0!==i.x&&(o.x=i.x),void 0!==i.y&&(o.y=i.y),void 0!==i.z&&(o.z=i.z)),n.set(t,o)}for(const[e,s]of n)t.points.push({x:s.x,y:s.y,label:`${e}\nSegment: ${s.segmentId} ${this.unravelSection.mutableSegmentIds.has(s.segmentId)?"MUTABLE":"IMMUTABLE"}\nLayer: ${s.z}`,color:this.colorMap[s.connectionName]||"#000"});const s=new Map;for(const t of this.unravelSection.allNodeIds)s.set(t,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0,estPf:0});for(const t of e.issues){const e=s.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"!==t.type&&"single_transition_crossing"!==t.type||e.numEntryExitLayerChanges++}for(const[t,e]of s.entries()){const n=this.nodeMap.get(t);e.estPf=Ph(n,e.numSameLayerCrossings,e.numEntryExitLayerChanges,e.numTransitionCrossings)}for(const e of this.unravelSection.allNodeIds){const n=this.nodeMap.get(e),o=this.unravelSection.mutableNodeIds.includes(e),i=s.get(e),r=[`${e} (${o?"MUT":"IMM"})`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${i.estPf.toFixed(3)}`,`TC: ${i.numTransitionCrossings}`,`SLC: ${i.numSameLayerCrossings}`,`EELC: ${i.numEntryExitLayerChanges}`].join("\n");t.rects.push({center:n.center,label:r,color:o?"green":"red",width:n.width/8,height:n.height/8})}for(const[e,s]of this.unravelSection.segmentPointsInSegment){if(s.length<=1)continue;const o=s.map(t=>n.get(t));for(let n=0;n<o.length-1;n++)t.lines.push({points:[{x:o[n].x,y:o[n].y},{x:o[n+1].x,y:o[n+1].y}],strokeColor:this.colorMap[e]||"#000"})}for(const[e,s]of n)for(const o of s.directlyConnectedSegmentPointIds)if(e<o){const e=n.get(o);if(!e)continue;const i=s.z===e.z,r=s.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:s.x,y:s.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[s.connectionName]||"#000"})}for(const s of e.issues){const e=this.nodeMap.get(s.capacityMeshNodeId);if("transition_via"===s.type)for(const o of s.segmentPoints){const s=n.get(o);t.circles.push({center:{x:s.x,y:s.y},radius:e.width/16,stroke:"#ff0000",fill:"rgba(255, 0, 0, 0.2)",label:`Via Issue\n${o}\nLayer: ${s.z}`})}else if("same_layer_crossing"===s.type)for(const[o,i]of[s.crossingLine1,s.crossingLine2]){const s=n.get(o),r=n.get(i);t.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:"rgba(255,0,0,0.2)",strokeWidth:e.width/32})}}for(const[s,o]of e.pointModifications){const e=n.get(s),o=this.unravelSection.segmentPointMap.get(s);t.circles.push({center:{x:e.x,y:e.y},radius:.05,stroke:"#0000ff",fill:"rgba(0, 0, 255, 0.2)",label:`${s}\nOriginal: (${o.x.toFixed(2)}, ${o.y.toFixed(2)}, ${o.z})\nNew: (${e.x.toFixed(2)}, ${e.y.toFixed(2)}, ${e.z})`})}return t}};import md from"object-hash";var gd=t=>(Math.round(20*t)/20).toFixed(2),yd=t=>(Math.round(1e3*t)/1e3).toFixed(3);Ne();var xd=class extends fd{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}computeCacheKeyAndTransform(){const t=this.nodeMap.get(this.rootNodeId),e=y(-t.center.x,-t.center.y),n=new Map,s=new Map,o=new Map,i=new Map,r=new Map,a=new Map;let c=0,h=0,l=0;const d=[...this.unravelSection.allNodeIds].sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.center.x!==s.center.x?n.center.x-s.center.x:n.center.y-s.center.y});for(const t of d){const e="node_"+c++;n.set(t,e),s.set(e,t)}const u=[...Array.from(this.unravelSection.segmentPointMap.entries()).sort(([,t],[,e])=>t.x!==e.x?t.x-e.x:t.y-e.y).map(([t])=>t)].sort();for(const t of u){const e="sp_"+l++;r.set(t,e),a.set(e,t);const n=this.unravelSection.segmentPointMap.get(t).segmentId;if(!o.has(n)){const t="seg_"+h++;o.set(n,t),i.set(t,n)}}const p={};for(const[t,s]of n.entries()){const n=this.nodeMap.get(t),o=g(e,n.center);p[s]={width:n.width,height:n.height,availableZ:n.availableZ,center:{x:gd(o.x),y:gd(o.y)}}}const f={};for(const[t,n]of r.entries()){const s=this.unravelSection.segmentPointMap.get(t),o=g(e,{x:s.x,y:s.y});f[n]={x:gd(o.x),y:gd(o.y),z:s.z}}const m={hyperParameters:this.hyperParameters,normalizedNodes:p,normalizedSegmentPoints:f,mutableHops:this.MUTABLE_HOPS},x=`unravelsec:${md(m)}`,v={realToCacheTransform:e,nodeIdMap:n,segmentIdMap:o,segmentPointIdMap:r,reverseNodeIdMap:s,reverseSegmentIdMap:i,reverseSegmentPointIdMap:a};return this.cacheKey=x,this.cacheToSolveSpaceTransform=v,{cacheKey:x,cacheToSolveSpaceTransform:v}}applyCachedSolution(t){if(!1===t.success)return void(this.failed=!0);if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available to apply cached solution.");const{reverseSegmentPointIdMap:e,reverseNodeIdMap:n}=this.cacheToSolveSpaceTransform,s=new Map;for(const[n,o]of t.bestCandidatePointModificationsDelta){const t=e.get(n);if(!t){console.warn(`Could not find original ID for normalized SP ID: ${n} when applying cache.`);continue}const i=this.unravelSection.segmentPointMap.get(t);if(!i){console.warn(`Could not find original segment point for ID: ${t} when applying cache.`);continue}const r={};if(void 0!==o.dx){const t=parseFloat(o.dx);Number.isNaN(t)?console.warn(`Failed to parse cached dx coordinate: ${o.dx}`):r.x=i.x+t}if(void 0!==o.dy){const t=parseFloat(o.dy);Number.isNaN(t)?console.warn(`Failed to parse cached dy coordinate: ${o.dy}`):r.y=i.y+t}void 0!==o.dz&&(r.z=i.z+o.dz),Object.keys(r).length>0&&s.set(t,r)}const o=dd(this.unravelSection,this.nodeMap,s);this.bestCandidate={pointModifications:s,issues:o,f:t.bestCandidateF,g:t.bestCandidateF,h:0,operationsPerformed:-1,candidateHash:hd(s)},this.cacheHit=!0,this.solved=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(this.failed)return void this.cacheProvider?.setCachedSolutionSync(this.cacheKey,{success:!1});if(!this.bestCandidate)return;const{segmentPointIdMap:t}=this.cacheToSolveSpaceTransform,e=[];for(const[n,s]of this.bestCandidate.pointModifications.entries()){const o=t.get(n);if(!o){console.warn(`Could not find normalized ID for original SP ID: ${n} when saving to cache.`);continue}const i=this.unravelSection.segmentPointMap.get(n);if(!i){console.warn(`Could not find original segment point for ID: ${n} when saving cache.`);continue}const r={};let a=!1;if(void 0!==s.x){const t=s.x-i.x,e=yd(t);0!==parseFloat(e)&&(r.dx=e,a=!0)}if(void 0!==s.y){const t=s.y-i.y,e=yd(t);0!==parseFloat(e)&&(r.dy=e,a=!0)}if(void 0!==s.z){const t=s.z-i.z;0!==t&&(r.dz=t,a=!0)}a&&e.push([o,r])}const n={success:!0,bestCandidatePointModificationsDelta:e,bestCandidateF:this.bestCandidate.f};this.cacheProvider?.setCachedSolutionSync(this.cacheKey,n)}},vd=class extends Ln{getSolverName(){return"UnravelMultiSectionSolver"}nodeMap;dedupedSegmentMap;dedupedSegments;nodeIdToSegmentIds;segmentIdToNodeIds;nodeToSegmentPointMap;segmentToSegmentPointMap;colorMap;tunedNodeCapacityMap;MAX_NODE_ATTEMPTS=2;MUTABLE_HOPS=1;ACCEPTABLE_PF=.05;MAX_ITERATIONS_WITHOUT_IMPROVEMENT=200;nodePfMap;attemptsToFixNode;activeSubSolver=null;segmentPointMap;cacheProvider=null;constructor({assignedSegments:t,colorMap:e,nodes:n,cacheProvider:s}){super(),this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.cacheHits=0,this.stats.cacheMisses=0,this.cacheProvider=s??null,this.MAX_ITERATIONS=1e6,this.dedupedSegments=(t=>{const e=[],n=new Map;let s=-1;for(const o of t){const t=`${o.start.x}-${o.start.y}-${o.end.x}-${o.end.y}-${o.availableZ.join(",")}`,i=n.get(t);i?o.nodePortSegmentId=i.nodePortSegmentId:(s++,o.nodePortSegmentId=`SEG${s}`,n.set(t,o),e.push(o))}return e})(t),this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t);this.nodeMap=new Map;for(const t of n)this.nodeMap.set(t.capacityMeshNodeId,t);this.nodeIdToSegmentIds=new Map,this.segmentIdToNodeIds=new Map,this.attemptsToFixNode=new Map;for(const e of t)this.segmentIdToNodeIds.set(e.nodePortSegmentId,[...this.segmentIdToNodeIds.get(e.nodePortSegmentId)??[],e.capacityMeshNodeId]),this.nodeIdToSegmentIds.set(e.capacityMeshNodeId,[...this.nodeIdToSegmentIds.get(e.capacityMeshNodeId)??[],e.nodePortSegmentId]);this.colorMap=e??{},this.tunedNodeCapacityMap=new Map;for(const[t,e]of this.nodeMap)this.tunedNodeCapacityMap.set(t,vh(e));const{segmentPointMap:o,nodeToSegmentPointMap:i,segmentToSegmentPointMap:r}=pd(this.dedupedSegments,this.segmentIdToNodeIds);this.segmentPointMap=o,this.nodeToSegmentPointMap=i,this.segmentToSegmentPointMap=r,this.nodePfMap=this.computeInitialPfMap()}computeInitialPfMap(){const t=new Map;for(const[e,n]of this.nodeMap.entries())t.set(e,this.computeNodePf(n));return t}computeNodePf(t){const{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}=(t=>{let e=0,n=0,s=0;const o=new Map;for(const e of t)o.has(e.connectionName)||o.set(e.connectionName,[]),o.get(e.connectionName).push(e);const i=[],r=[];for(const[t,e]of o.entries()){if(e.length<2)continue;const s=e[0];for(let o=1;o<e.length;o++){const a=e[o],c={connectionName:t,z:s.z,points:[s,a]};s.z!==a.z?(n++,r.push({connectionName:t,points:[s,a]})):i.push(c)}}for(let t=0;t<i.length;t++)for(let n=t+1;n<i.length;n++){const s=i[t],o=i[n];s.z===o.z&&L(s.points[0],s.points[1],o.points[0],o.points[1])&&e++}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){const n=r[t],o=r[e];L(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}for(let t=0;t<r.length;t++)for(let e=0;e<i.length;e++){const n=r[t],o=i[e];L(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}})((this.nodeToSegmentPointMap.get(t.capacityMeshNodeId)??[]).map(t=>this.segmentPointMap.get(t)));return Ph(t,e,n,s)}_step(){if(this.iterations>=this.MAX_ITERATIONS-1)return void(this.solved=!0);if(!this.activeSubSolver){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_NODE_ATTEMPTS)>e&&(e=s,t=n)}if(!t||e<this.ACCEPTABLE_PF)return void(this.solved=!0);this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.activeSubSolver=new xd({dedupedSegments:this.dedupedSegments,dedupedSegmentMap:this.dedupedSegmentMap,nodeMap:this.nodeMap,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,colorMap:this.colorMap,rootNodeId:t,MUTABLE_HOPS:this.MUTABLE_HOPS,segmentPointMap:this.segmentPointMap,nodeToSegmentPointMap:this.nodeToSegmentPointMap,segmentToSegmentPointMap:this.segmentToSegmentPointMap,cacheProvider:this.cacheProvider})}this.activeSubSolver.step();const{bestCandidate:t,originalCandidate:e,lastProcessedCandidate:n}=this.activeSubSolver;if(this.activeSubSolver.failed)return this.stats.failedOptimizations+=1,void(this.activeSubSolver=null);if(this.activeSubSolver.solved){this.activeSubSolver.cacheHit?this.stats.cacheHits+=1:this.stats.cacheMisses+=1;if(t&&t.g<e.g){this.stats.successfulOptimizations+=1;for(const[e,n]of t.pointModifications.entries()){const t=this.segmentPointMap.get(e);t.x=n.x??t.x,t.y=n.y??t.y,t.z=n.z??t.z}for(const t of this.activeSubSolver.unravelSection.allNodeIds)this.nodePfMap.set(t,this.computeNodePf(this.nodeMap.get(t)))}else this.stats.failedOptimizations+=1;this.activeSubSolver=null}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Multi Section Solver"};for(const[e,n]of this.nodeMap.entries()){const s=this.nodePfMap.get(e)||0,o=Math.min(s,1),i=`rgb(${Math.floor(255*o)}, ${Math.floor(255*(1-o))}, 0)`;0===(this.attemptsToFixNode.get(e)??0)&&0===o||t.rects.push({center:n.center,label:[e,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${s.toFixed(3)}`].join("\n"),color:i,width:n.width/8,height:n.height/8})}for(const e of this.segmentPointMap.values()){const n=this.dedupedSegmentMap.get(e.segmentId);t.points.push({x:e.x,y:e.y,label:[e.segmentPointId,e.segmentId,`z: ${e.z}`,`segment.availableZ: ${n?.availableZ.join(",")}`].join("\n"),color:this.colorMap[e.connectionName]||"#000"})}const e=new Map;for(const t of this.segmentPointMap.values())e.has(t.segmentId)||e.set(t.segmentId,[]),e.get(t.segmentId).push(t);for(const[n,s]of e.entries()){if(s.length<2)continue;const e=[...s].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y);for(let s=0;s<e.length-1;s++)t.lines.push({points:[{x:e[s].x,y:e[s].y},{x:e[s+1].x,y:e[s+1].y}],strokeColor:this.colorMap[n]||"#000"})}const n=new Set,s=Array.from(this.segmentPointMap.values());for(let e=0;e<s.length;e++){const o=s[e];for(let i=e+1;i<s.length;i++){const e=s[i];if(o.connectionName!==e.connectionName||o.segmentId===e.segmentId)continue;if(o.capacityMeshNodeIds.some(t=>e.capacityMeshNodeIds.includes(t))){const s=`${o.segmentPointId}-${e.segmentPointId}`;if(n.has(s))continue;n.add(s);const i=o.z===e.z,r=o.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:o.x,y:o.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[o.connectionName]||"#666"})}}}return t}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.dedupedSegments){const n=e.nodePortSegmentId;for(const e of this.segmentIdToNodeIds.get(n)){const n=this.nodeMap.get(e);t.has(e)||t.set(e,{capacityMeshNodeId:e,portPoints:[],center:n.center,width:n.width,height:n.height})}}for(const e of this.segmentPointMap.values())for(const n of e.capacityMeshNodeIds){const s=t.get(n);s&&s.portPoints.push({x:e.x,y:e.y,z:e.z,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName})}return Array.from(t.values())}};function bd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Pd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipeline1_OriginalUnravel"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;viaDiameter;minTraceWidth;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[bd("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),bd("nodeSolver",Yl,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),bd("singleLayerNodeMerger",rd,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),bd("strawSolver",ad,t=>[{nodes:t.singleLayerNodeMerger?.newNodes}],{onSolved:t=>{t.capacityNodes=t.strawSolver?.getResultNodes()}}),bd("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),bd("deadEndSolver",sd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),bd("initialPathingSolver",jl,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),bd("pathingOptimizer",nd,t=>[{initialPathingSolver:t.initialPathingSolver,simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,cacheProvider:t.cacheProvider,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),bd("edgeToPortSegmentSolver",Rl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.pathingOptimizer?.getCapacityPaths()||[],colorMap:t.colorMap}]),bd("segmentToPointSolver",Xl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),bd("unravelMultiSectionSolver",vd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),bd("highDensityRouteSolver",uh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),bd("highDensityStitchSolver",od,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),bd("traceSimplificationSolver",_l,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.initialPathingSolver?.visualize(),c=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),l=this.segmentToPointSolver?.visualize(),d=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensityStitchSolver?.visualize(),f=this.traceSimplificationSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,c,h,l,d,u?jn(y,u):null,p,f,this.solved?jn(y,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}};function Sd(t){const{pos:e,segments:n,dir:s,keepoutRadius:o}=t;let i=1/0;const r=o/4,a={x:e.x-s.x*r,y:e.y-s.y*r},c={x:e.x+s.x*r,y:e.y+s.y*r};for(const t of n){const e=K(a,c,t.start,t.end);i=Math.min(i,e)}return i}function Md(t,e,n,s){const o=Nd(n,s,t),i=Nd(n,s,e),r=Nd(t,e,n),a=Nd(t,e,s);if((o>0&&i<0||o<0&&i>0)&&(r>0&&a<0||r<0&&a>0))return!0;const c=1e-4;return!!(Math.abs(o)<c&&Id(n,s,t))||(!!(Math.abs(i)<c&&Id(n,s,e))||(!!(Math.abs(r)<c&&Id(t,e,n))||!!(Math.abs(a)<c&&Id(t,e,s))))}function Nd(t,e,n){return(n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y)}function Id(t,e,n){return n.x>=Math.min(t.x,e.x)-1e-4&&n.x<=Math.max(t.x,e.x)+1e-4&&n.y>=Math.min(t.y,e.y)-1e-4&&n.y<=Math.max(t.y,e.y)+1e-4}function _d(t,e,n){for(const s of n)if(Md(t,e,s.start,s.end))return!1;return!0}var Cd=1e-4;function Td(t){const e=t.width/2,n=t.height/2,s=t.center.x,o=t.center.y,i={x:s-e,y:o+n},r={x:s+e,y:o+n},a={x:s-e,y:o-n},c={x:s+e,y:o-n};return[{start:i,end:r},{start:r,end:c},{start:c,end:a},{start:a,end:i}]}function Ed(t,e,n=.1){const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(0===i)return[];const r=-(o/i),a=s/i,c=n/2;return[{start:{x:t.x+r*c,y:t.y+a*c},end:{x:e.x+r*c,y:e.y+a*c}},{start:{x:t.x-r*c,y:t.y-a*c},end:{x:e.x-r*c,y:e.y-a*c}}]}function wd(t,e,n){const s=Math.hypot(t.start.x-e.x,t.start.y-e.y),o=Math.hypot(t.end.x-e.x,t.end.y-e.y);if(s<=n||o<=n)return!0;const i=t.end.x-t.start.x,r=t.end.y-t.start.y,a=i*i+r*r;if(0===a)return!1;const c=Math.max(0,Math.min(1,((e.x-t.start.x)*i+(e.y-t.start.y)*r)/a)),h=t.start.x+c*i,l=t.start.y+c*r;return Math.hypot(h-e.x,l-e.y)<=n}function Rd(t,e,n){if(!n||0===n.length)return!1;for(const s of n){const n=Math.abs(t.x-s.start.x)<Cd&&Math.abs(t.y-s.start.y)<Cd&&Math.abs(e.x-s.end.x)<Cd&&Math.abs(e.y-s.end.y)<Cd,o=Math.abs(t.x-s.end.x)<Cd&&Math.abs(t.y-s.end.y)<Cd&&Math.abs(e.x-s.start.x)<Cd&&Math.abs(e.y-s.start.y)<Cd;if(n||o)return!0}return!1}function Od(t,e,n,s,o){const i=[];for(let r=0;r<t.length-1;r++){const a=t[r],c=t[r+1];Rd(a,c,o)||wd({start:a,end:c},n,s+e)&&i.push(...Ed(a,c,e))}return i}var Ad=1e-4;function zd(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=o*a-i*r;if(Math.abs(c)<1e-10)return null;const h=n.x-t.x,l=n.y-t.y,d=(h*a-l*r)/c,u=(h*i-l*o)/c,p=1e-6;return d>p&&d<.999999&&u>p&&u<.999999?{x:t.x+d*o,y:t.y+d*i}:null}function Dd(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Ad&&Math.abs(t.y-n.start.y)<Ad||Math.abs(t.x-n.end.x)<Ad&&Math.abs(t.y-n.end.y)<Ad)return!0;return!1}function Ld(t,e,n,s){if(!s||0===s.length)return!1;for(let o=e;o<=n;o++)if(o>=0&&o<t.length&&Dd(t[o],s))return!0;return!1}var Fd=1e-4,Yd=class extends Ln{constructor(t){super(),this.input=t;const e=t.srj?.layerCount??2;this.input={...t,obstacles:ll(t.obstacles,e)},this.MAX_ITERATIONS=1e6,this.originalHdRoutes=[...this.input.hdRoutes],this.hdRoutes=this.input.hdRoutes,this.KEEPOUT_RADIUS_SCHEDULE=t.keepoutRadiusSchedule??[.3,.5,.5],this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[0]??.15,this.unprocessedRoutes=[...this.hdRoutes],this.smoothedCursorRoutes=[...this.unprocessedRoutes];const n=[...this.input.obstacles,...this.getJumperPadObstacles()];this.obstacleSHI=new nl("flatbush",n),this.boardOutlineRoutes=this.createBoardOutlineRoutes(),this.hdRouteSHI=new cl([...this.hdRoutes,...this.boardOutlineRoutes]);for(const[t,e,n]of this.hdRoutes.flatMap(t=>[[t.route[0],t.connectionName,t.rootConnectionName],[t.route[t.route.length-1],t.connectionName,t.rootConnectionName]])){const s=this.obstacleSHI.searchArea(t.x,t.y,.01,.01).filter(e=>e.zLayers?.includes(t.z));if(0===s.length)continue;const o=s[0];this.input.connMap.addConnections([[e,n,...o.offBoardConnectsTo??[],o.obstacleId,...o.connectedTo].filter(Boolean)])}}getSolverName(){return"TraceKeepoutSolver"}originalHdRoutes;hdRoutes;redrawnHdRoutes=[];KEEPOUT_RADIUS_SCHEDULE;currentScheduleIndex=0;currentKeepoutRadius;unprocessedRoutes=[];smoothedCursorRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;lastCursorPosition=null;drawPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;recordedDrawPositions=[];lastCollidingSegments=[];currentTraceJumperSegments=new Map;obstacleSHI;hdRouteSHI;boardOutlineRoutes=[];getSmoothDistance(){return this.currentKeepoutRadius}getJumperPadObstacles(){const t=[];if(!this.input.jumpers)return t;for(const e of this.input.jumpers)for(const n of e.pads)t.push({...n,zLayers:[0]});return t}buildJumperSegmentMap(t){const e=new Map;if(!t.jumpers||0===t.jumpers.length)return e;const n=t.route;for(const s of t.jumpers){let t=-1,o=1/0;for(let e=0;e<n.length-1;e++){const i=n[e],r=n[e+1],a=Math.sqrt((i.x-s.start.x)**2+(i.y-s.start.y)**2),c=Math.sqrt((r.x-s.end.x)**2+(r.y-s.end.y)**2),h=a+c,l=Math.sqrt((i.x-s.end.x)**2+(i.y-s.end.y)**2),d=Math.sqrt((r.x-s.start.x)**2+(r.y-s.start.y)**2),u=l+d,p=Math.min(h,u);(h<=u?a:l)<1&&(h<=u?c:d)<1&&p<o&&(o=p,t=e)}t>=0&&e.set(t,s)}return e}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.currentScheduleIndex++,this.currentScheduleIndex<this.KEEPOUT_RADIUS_SCHEDULE.length?(this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[this.currentScheduleIndex],this.unprocessedRoutes=Gn([...this.processedRoutes],this.currentScheduleIndex),this.smoothedCursorRoutes=[...this.unprocessedRoutes],this.processedRoutes=[],void(this.hdRouteSHI=new cl([...this.unprocessedRoutes,...this.boardOutlineRoutes]))):(this.redrawnHdRoutes=this.processedRoutes,void(this.solved=!0));if(this.currentTrace=t,this.currentTrace.route.length<2)return this.processedRoutes.push(this.currentTrace),void(this.currentTrace=null);this.currentTraceJumperSegments=this.buildJumperSegmentMap(this.currentTrace);const e=this.currentTrace.route[0];return this.cursorPosition={...e},this.lastCursorPosition={...e},this.drawPosition={x:e.x,y:e.y},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,void(this.recordedDrawPositions=[{...e}])}this.lastCursorPosition={...this.cursorPosition};const t=this.stepCursorForward();if("end"===t)return void this.finalizeCurrentTrace();if("jumper"===t)return void(this.drawPosition={x:this.cursorPosition.x,y:this.cursorPosition.y});const e=this.getCollidingSegments(this.cursorPosition);this.lastCollidingSegments=e;const n=function(t){const{cursorPosition:e,lastCursorPosition:n,collidingSegments:s,keepoutRadius:o}=t;if(0===s.length)return null;const i=1e-4,r=e.x-n.x,a=e.y-n.y,c=Math.sqrt(r*r+a*a),h=c>i?{x:r/c,y:a/c}:{x:1,y:0},l=-h.y,d=h.x,u=Sd({pos:e,segments:s,dir:h,keepoutRadius:o});if(u>=o)return null;for(let t=1;t<=20;t++){const n=t/20*o,i={x:e.x+l*n,y:e.y+d*n},r=Sd({pos:i,segments:s,dir:h,keepoutRadius:o}),a={x:e.x-l*n,y:e.y-d*n},c=Sd({pos:a,segments:s,dir:h,keepoutRadius:o}),u=r>=o&&_d(e,i,s),p=c>=o&&_d(e,a,s);if(u&&p)return r>=c?i:a;if(u)return i;if(p)return a}const p=o,f=[];for(let t=-60;t<=60;t++){const n=t/60*p,i={x:e.x+l*n,y:e.y+d*n},r=Sd({pos:i,segments:s,dir:h,keepoutRadius:o}),a=_d(e,i,s);f.push({pos:i,clearance:r,dist:Math.abs(n),pathClear:a,index:t})}const m=f.filter(t=>t.pathClear),g=f.findIndex(t=>0===t.index),y=g>=0?g:Math.floor(f.length/2);let x=null;for(let t=y+1;t<f.length-1;t++){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){x=n;break}}let v=null;for(let t=y-1;t>0;t--){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){v=n;break}}let b=null,P=null;if(m.length>0){const t=m.findIndex(t=>0===t.index),e=t>=0?t:Math.floor(m.length/2);for(let t=e+1;t<m.length-1;t++){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){b=n;break}}for(let t=e-1;t>0;t--){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){P=n;break}}}const S=[x,v,b,P,f.find(t=>0===t.index)].filter(t=>null!=t),M=new Set,N=S.filter(t=>{const e=`${t.pos.x.toFixed(6)},${t.pos.y.toFixed(6)}`;return!M.has(e)&&(M.add(e),!0)});if(0===N.length){let t=f[0];if(!t)return null;for(const e of f)e.clearance>t.clearance&&(t=e);return Math.sqrt((t.pos.x-e.x)**2+(t.pos.y-e.y)**2)>i?t.pos:null}let I;if(u<.15*o){I=N[0];for(const t of N)t.clearance>I.clearance&&(I=t)}else{const t=N.filter(t=>t.pathClear),e=t.length>0?t:N;I=e[0];for(const t of e)t.clearance>I.clearance&&(I=t)}return Math.sqrt((I.pos.x-e.x)**2+(I.pos.y-e.y)**2)>i?I.pos:null}({cursorPosition:this.cursorPosition,lastCursorPosition:this.lastCursorPosition,collidingSegments:e,keepoutRadius:this.currentKeepoutRadius});this.drawPosition=n??{...this.cursorPosition};const s=this.recordedDrawPositions[this.recordedDrawPositions.length-1];if(s&&this.drawPosition){const t={x:s.x,y:s.y,z:s.z},e={x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z};this.segmentIntersectsOtherRoutes(t,e)&&(this.drawPosition={...this.cursorPosition})}this.recordedDrawPositions.push({x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z})}getStepDistance(){return this.currentKeepoutRadius/2}getJumperAtCurrentSegmentStart(){return this.currentTraceSegmentT>Fd?null:this.currentTraceJumperSegments.get(this.currentTraceSegmentIndex)??null}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return"end";const t=this.currentTrace.route;let e=this.getStepDistance();for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return"end";const n=this.getJumperAtCurrentSegmentStart();if(n){const e=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1],o=Math.sqrt((e.x-n.start.x)**2+(e.y-n.start.y)**2),i=Math.sqrt((e.x-n.end.x)**2+(e.y-n.end.y)**2),r=o<=i?n.start:n.end,a=o<=i?n.end:n.start;return this.recordedDrawPositions.push({x:r.x,y:r.y,z:e.z,insideJumperPad:!0}),this.recordedDrawPositions.push({x:a.x,y:a.y,z:s.z,insideJumperPad:!0}),this.cursorPosition={x:a.x,y:a.y,z:s.z},this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,"jumper"}const s=t[this.currentTraceSegmentIndex],o=t[this.currentTraceSegmentIndex+1],i=o.x-s.x,r=o.y-s.y,a=Math.sqrt(i*i+r*r);if(0===a){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const c=this.currentTraceSegmentT*a,h=a-c;if(e<=h){const t=c+e;return this.currentTraceSegmentT=t/a,this.cursorPosition={x:s.x+i*this.currentTraceSegmentT,y:s.y+r*this.currentTraceSegmentT,z:s.z},"stepped"}if(e-=h,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},"end"}}return"stepped"}getCollidingSegments(t){if(!this.currentTrace)return[];const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.currentKeepoutRadius,s=[],o=this.obstacleSHI.searchArea(t.x,t.y,n,n).filter(e=>e.zLayers?.includes(t.z));for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.input.connMap.areIdsConnected(e,n.obstacleId))continue;let o=!1;for(const t of n.connectedTo)if(this.input.connMap.areIdsConnected(e,t)){o=!0;break}o||s.push(...Td(n))}const i=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:o}of i){const i=o.rootConnectionName??o.connectionName;if(i===e)continue;if(this.input.connMap.areIdsConnected(e,i))continue;const r=o.traceThickness??.15;s.push(...Od(o.route,r,{x:t.x,y:t.y},n,o.jumpers))}return s}positionHasCollision(t,e=0){const n=this.getCollidingSegments(t);for(const s of n)if(X(t,s.start,s.end)<=this.currentKeepoutRadius+e)return!0;return!1}segmentIntersectsOtherRoutes(t,e){if(!this.currentTrace)return!1;const n=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,s=[...this.unprocessedRoutes,...this.smoothedCursorRoutes,...this.processedRoutes];for(const o of s){if((o.rootConnectionName??o.connectionName)!==n)for(let n=0;n<o.route.length-1;n++){const s=o.route[n],i=o.route[n+1];if((s.z===t.z||i.z===t.z)&&((!s.insideJumperPad||!i.insideJumperPad)&&L({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:i.x,y:i.y})))return!0}}return!1}finalizeCurrentTrace(){if(!this.currentTrace)return;const t=this.currentTrace.route[this.currentTrace.route.length-1],e=this.recordedDrawPositions[this.recordedDrawPositions.length-1];e&&e.x===t.x&&e.y===t.y||this.recordedDrawPositions.push({...t});const n=function(t,e){if(t.length<4)return t;let n=[...t],s=!0;for(;s;){s=!1;for(let t=0;t<n.length-1&&!s;t++){const o=n[t],i=n[t+1];if(o.z===i.z)for(let r=t+2;r<n.length-1&&!s;r++){if(r===t+1)continue;const a=n[r],c=n[r+1];if(a.z!==c.z||o.z!==a.z)continue;const h=zd(o,i,a,c);if(h){if(Ld(n,t+1,r,e))continue;const i=[];for(let e=0;e<=t;e++)i.push(n[e]);i.push({x:h.x,y:h.y,z:o.z});for(let t=r+1;t<n.length;t++)i.push(n[t]);n=i,s=!0}}}}return n}(this.simplifyRoute(this.recordedDrawPositions,this.currentTrace.jumpers),this.currentTrace.jumpers),s={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:this.currentTrace.traceThickness,viaDiameter:this.currentTrace.viaDiameter,route:n,vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(s),this.hdRouteSHI.removeRoute(this.currentTrace.connectionName),this.hdRouteSHI.addRoute(s),this.currentTrace=null,this.cursorPosition=null,this.lastCursorPosition=null,this.drawPosition=null,this.recordedDrawPositions=[]}isJumperEndpoint(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Fd&&Math.abs(t.y-n.start.y)<Fd||Math.abs(t.x-n.end.x)<Fd&&Math.abs(t.y-n.end.y)<Fd)return!0;return!1}simplifyRoute(t,e){if(t.length<=2)return t;const n=[t[0]];for(let s=1;s<t.length-1;s++){const o=n[n.length-1],i=t[s],r=t[s+1];if(this.isJumperEndpoint(i,e)){n.push(i);continue}if(i.z!==o.z||i.z!==r.z){n.push(i);continue}const a=i.x-o.x,c=i.y-o.y,h=r.x-i.x,l=a*(r.y-i.y)-c*h,d=1e-6;Math.abs(l)>d&&n.push(i)}return n.push(t[t.length-1]),n}createBoardOutlineRoutes(){const t=[];if(!this.input.srj)return t;const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];const o=this.input.srj.layerCount??2;for(let e=0;e<s.length;e++){const n=s[e],i=s[(e+1)%s.length];for(let s=0;s<o;s++)t.push({connectionName:`__board_outline___${e}_z${s}`,traceThickness:.01,viaDiameter:0,route:[{x:n.x,y:n.y,z:s},{x:i.x,y:i.y,z:s}],vias:[]})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:`Trace Keepout Solver (radius: ${this.currentKeepoutRadius.toFixed(2)})`};for(const e of this.originalHdRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"rgba(0,0,0,0.25)",strokeWidth:1.5*(e.traceThickness??.15)})}if(this.input.jumpers)for(const e of this.input.jumpers){for(const n of e.pads){const e=n.connectedTo.length>0?n.connectedTo.join(", "):"unused",s=n.connectedTo.length>0?this.input.colorMap[n.connectedTo[0]]||"#888888":"rgba(128, 128, 128, 0.5)";t.rects.push({center:n.center,width:n.width,height:n.height,fill:s,stroke:"rgba(0, 0, 0, 0.5)",label:`Jumper pad (${e})`})}e.pads.length>=2&&t.lines.push({points:[e.pads[0].center,e.pads[1].center],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.2,label:"Jumper body"})}for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}if(this.input.srj){const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];for(let e=0;e<s.length;e++){const n=s[e],o=s[(e+1)%s.length];t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"rgba(0, 128, 0, 0.6)",strokeWidth:.1,label:"Board outline"})}}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888",s=new Set;if(e.jumpers&&e.jumpers.length>0)for(const t of e.jumpers)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1],r=Math.abs(o.x-t.start.x)<Fd&&Math.abs(o.y-t.start.y)<Fd&&Math.abs(i.x-t.end.x)<Fd&&Math.abs(i.y-t.end.y)<Fd,a=Math.abs(o.x-t.end.x)<Fd&&Math.abs(o.y-t.end.y)<Fd&&Math.abs(i.x-t.start.x)<Fd&&Math.abs(i.y-t.start.y)<Fd;if(r||a){s.add(n);break}}for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];s.has(n)?t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:"rgba(128, 128, 128, 0.6)",strokeDash:"2 2",label:`${e.connectionName} (jumper segment - fixed)`}):o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Gh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}if(this.currentTrace&&this.recordedDrawPositions.length>0){this.input.colorMap[this.currentTrace.connectionName];for(let e=0;e<this.recordedDrawPositions.length-1;e++){const n=this.recordedDrawPositions[e],s=this.recordedDrawPositions[e+1];t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"green",strokeWidth:this.currentTrace.traceThickness})}if(this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentKeepoutRadius,stroke:"orange",fill:"none"}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}),this.lastCursorPosition)){const e=this.cursorPosition.x-this.lastCursorPosition.x,n=this.cursorPosition.y-this.lastCursorPosition.y,s=Math.sqrt(e*e+n*n),o=s>1e-4?{x:e/s,y:n/s}:{x:1,y:0},i=this.currentKeepoutRadius/4,r={x:this.cursorPosition.x-o.x*i,y:this.cursorPosition.y-o.y*i},a={x:this.cursorPosition.x+o.x*i,y:this.cursorPosition.y+o.y*i};t.lines.push({points:[r,a],strokeColor:"cyan",strokeWidth:.05,label:"Projected segment"})}this.drawPosition&&t.points.push({x:this.drawPosition.x,y:this.drawPosition.y,color:"lime",label:"Draw"});for(const e of this.lastCollidingSegments)t.lines.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:"rgba(255, 0, 255, 0.8)",strokeWidth:.02,label:"Colliding segment"})}if(!this.solved)for(const e of this.smoothedCursorRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"gray"})}return t}getRedrawnHdRoutes(){return this.redrawnHdRoutes}},Xd=class extends Ln{constructor(t){super(),this.input=t,this.unprocessedObstacles=ll(this.input.srj.obstacles,this.input.srj.layerCount).filter(t=>t.offBoardConnectsTo&&t.offBoardConnectsTo.length>0),this.unprocessedObstacles.forEach((t,e)=>{t.obstacleId=t.obstacleId??`__obs${e}`}),this.offBoardConnMap=new Uh({}),this.offBoardConnMap.addConnections(this.unprocessedObstacles.filter(t=>t.offBoardConnectsTo?.length).map(t=>[t.obstacleId,...t.offBoardConnectsTo??[]])),this.nodeTree=new $n(this.input.capacityMeshNodes)}getSolverName(){return"RelateNodesToOffBoardConnectionsSolver"}unprocessedObstacles;nodeTree;offBoardConnMap;nodesInNet=new Map;lastProcessedObstacle;_step(){const t=this.unprocessedObstacles.pop();if(this.lastProcessedObstacle=t,!t)return void(this.solved=!0);const e=this.offBoardConnMap.getNetConnectedToId(t.obstacleId),n=this.nodeTree.getNodesInArea(t.center.x,t.center.y,.01,.01).filter(e=>e.availableZ.some(e=>t.zLayers?.includes(e))).filter(e=>Math.abs(e.center.x-t.center.x)<.01&&Math.abs(e.center.y-t.center.y)<.01),s=n.map(t=>t.capacityMeshNodeId),o=this.nodesInNet.get(e)??[],i=[...o.map(t=>t.capacityMeshNodeId),...s];for(const t of o)t._offBoardConnectedCapacityMeshNodeIds=i;for(const t of n)t._offBoardConnectedCapacityMeshNodeIds=i,t._offBoardConnectionId=e;this.nodesInNet.set(e,[...o,...n])}getOutput(){return{capacityNodes:this.input.capacityMeshNodes}}visualize(){const t={rects:[],lines:[],points:[],circles:[]},e=new Set;for(const[t,n]of this.nodesInNet)for(const t of n)e.add(t.capacityMeshNodeId);for(const n of this.input.capacityMeshNodes)e.has(n.capacityMeshNodeId)||t.rects.push({center:n.center,width:n.width-.1,height:n.height-.1,fill:"rgba(0, 0, 0, 0.2)"});this.lastProcessedObstacle&&t.rects.push({center:this.lastProcessedObstacle.center,width:this.lastProcessedObstacle.width,height:this.lastProcessedObstacle.height,fill:"rgba(255, 0, 0, 0.5)"});for(const[e,n]of this.nodesInNet.entries()){for(const s of n)t.rects.push({center:s.center,width:s.width,height:s.height,fill:_n(e,.2),label:`OffBoardConn: ${e}`});for(const s of n)for(const o of n)s.capacityMeshNodeId!==o.capacityMeshNodeId&&t.lines.push({points:[s.center,o.center],strokeColor:_n(e,1)})}return t}},kd=.1,$d=.1;function Bd(t,e,n,s,o,i){return(o-t)*(s-e)-(i-e)*(n-t)}function jd(t,e,n,s,o,i){return Math.min(t,n)<=o&&o<=Math.max(t,n)&&Math.min(e,s)<=i&&i<=Math.max(e,s)}function Wd(t,e,n,s,o,i,r,a){const c=Bd(o,i,r,a,t,e),h=Bd(o,i,r,a,n,s),l=Bd(t,e,n,s,o,i),d=Bd(t,e,n,s,r,a);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)||(!(0!==c||!jd(o,i,r,a,t,e))||(!(0!==h||!jd(o,i,r,a,n,s))||(!(0!==l||!jd(t,e,n,s,o,i))||!(0!==d||!jd(t,e,n,s,r,a)))))}function Hd(t,e,n,s,o,i){const r=o-n,a=i-s,c=t-n,h=e-s,l=r*r+a*a;if(0===l){return{x:n,y:s,distSq:c*c+h*h}}let d=(c*r+h*a)/l;d=Math.max(0,Math.min(1,d));const u=n+d*r,p=s+d*a,f=t-u,m=e-p;return{x:u,y:p,distSq:f*f+m*m}}var Ud=class extends Ln{getSolverName(){return"SimpleHighDensitySolver"}unsolvedNodes;allNodes;routes;colorMap;traceWidth;viaDiameter;numMovablePoints;currentNode=null;lastNode=null;currentNodeStep=0;routesInProgress=[];pushMargin;currentNodeBounds=null;constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.1,viaDiameter:s=.3,pushMargin:o=.3,numMovablePoints:i=2}){if(super(),i<1||i>3)throw new Error(`numMovablePoints must be 1, 2, or 3, got ${i}`);this.allNodes=[...t],this.unsolvedNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.viaDiameter=s,this.numMovablePoints=i,this.pushMargin=o,this.MAX_ITERATIONS=10*t.length+1}_step(){if(null===this.currentNode){if(0===this.unsolvedNodes.length)return void(this.solved=!0);this.lastNode=this.currentNode,this.currentNode=this.unsolvedNodes.pop(),this.currentNodeStep=0,this.routesInProgress=[],this._initializeRoutesForCurrentNode()}this.currentNodeStep>0&&this._runForceDirectedStep(),this.currentNodeStep++,this.currentNodeStep>=10&&(this._finalizeRoutesForCurrentNode(),this.lastNode=this.currentNode,this.currentNode=null)}_initializeRoutesForCurrentNode(){const t=this.currentNode,e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2;this.currentNodeBounds={minX:e,maxX:n,minY:s,maxY:o};const i=new Map;for(const e of t.portPoints)i.has(e.connectionName)||i.set(e.connectionName,[]),i.get(e.connectionName).push({x:e.x,y:e.y,z:e.z,rootConnectionName:e.rootConnectionName});for(const[t,e]of i){if(e.length<2)continue;const n=e[0],s=e[e.length-1],o=n.z,i=s.x-n.x,r=s.y-n.y,a=Math.sqrt(i*i+r*r),c=a>0?i/a:0,h=a>0?r/a:0,l=[];this.numMovablePoints>=1&&l.push({x:n.x+c*$d,y:n.y+h*$d,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=2&&l.push({x:s.x-c*$d,y:s.y-h*$d,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=3&&l.push({x:n.x+i/2,y:n.y+r/2,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.routesInProgress.push({connectionName:t,rootConnectionName:n.rootConnectionName,startPoint:{x:n.x,y:n.y,z:o},endPoint:{x:s.x,y:s.y,z:o},movablePoints:l})}}_runForceDirectedStep(){const t=this.currentNodeBounds,e=[];for(const t of this.routesInProgress)e.push(...t.movablePoints);const n=new Map;for(const t of e)n.set(t,{fx:0,fy:0});const s=.3+this.pushMargin,o=new Map;for(const t of this.routesInProgress){const e=[{x:t.startPoint.x,y:t.startPoint.y,movablePoint:null}];1===t.movablePoints.length?e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}):2===t.movablePoints.length?(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})):3===t.movablePoints.length&&(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[2].x,y:t.movablePoints[2].y,movablePoint:t.movablePoints[2]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})),e.push({x:t.endPoint.x,y:t.endPoint.y,movablePoint:null}),o.set(t,e)}for(const i of e){const e=n.get(i),r=i.x-t.minX,a=t.maxX-i.x,c=t.maxY-i.y,h=i.y-t.minY;r<s&&(e.fx+=kd*(s-r)),a<s&&(e.fx-=kd*(s-a)),h<s&&(e.fy+=kd*(s-h)),c<s&&(e.fy-=kd*(s-c));for(const t of this.routesInProgress){if(t.rootConnectionName===i.rootConnectionName)continue;const r=o.get(t);for(let t=0;t<r.length-1;t++){const o=r[t],a=r[t+1],c=Hd(i.x,i.y,o.x,o.y,a.x,a.y),h=Math.sqrt(c.distSq);if(h>0&&h<2*s){const t=i.x-c.x,s=i.y-c.y,r=.002/c.distSq,h=r*t,l=r*s;e.fx+=h,e.fy+=l;const d=o.movablePoint,u=a.movablePoint;if(d&&u){const t=n.get(d),e=n.get(u);t.fx-=h/2,t.fy-=l/2,e.fx-=h/2,e.fy-=l/2}else if(d){const t=n.get(d);t.fx-=h,t.fy-=l}else if(u){const t=n.get(u);t.fx-=h,t.fy-=l}}}}}const i=t=>t.movablePoint?{x:t.movablePoint.x,y:t.movablePoint.y}:{x:t.x,y:t.y},r=t=>{let e=null;for(const n of this.routesInProgress)if(n.movablePoints.includes(t)){e=n;break}if(!e)return!1;const n=o.get(e);let s=-1;for(let e=0;e<n.length;e++)if(n[e].movablePoint===t){s=e;break}if(-1===s)return!1;const r=[];if(s>0){const e=i(n[s-1]);r.push({ax:e.x,ay:e.y,bx:t.x,by:t.y})}if(s<n.length-1){const e=i(n[s+1]);r.push({ax:t.x,ay:t.y,bx:e.x,by:e.y})}for(const t of this.routesInProgress){if(t.rootConnectionName===e.rootConnectionName)continue;const n=o.get(t);for(let t=0;t<n.length-1;t++){const e=i(n[t]),s=i(n[t+1]);for(const t of r)if(Wd(t.ax,t.ay,t.bx,t.by,e.x,e.y,s.x,s.y))return!0}}return!1};for(const s of e){const e=n.get(s);s.forceX=e.fx,s.forceY=e.fy;const o=s.x,i=s.y;s.x+=e.fx,s.y+=e.fy,s.x=Math.max(t.minX,Math.min(t.maxX,s.x)),s.y=Math.max(t.minY,Math.min(t.maxY,s.y)),r(s)&&(s.x=o,s.y=i)}}_finalizeRoutesForCurrentNode(){for(const t of this.routesInProgress){const{connectionName:e,rootConnectionName:n,startPoint:s,endPoint:o,movablePoints:i}=t,r=[{x:s.x,y:s.y,z:s.z}];1===i.length?r.push({x:i[0].x,y:i[0].y,z:i[0].z}):2===i.length?(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})):3===i.length&&(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[2].x,y:i[2].y,z:i[2].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})),r.push({x:o.x,y:o.y,z:o.z});const a={connectionName:e,rootConnectionName:n,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:r,vias:[]};this.routes.push(a)}this.routesInProgress=[]}_getNodeBounds(t){return{minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.unsolvedNodes){if(e===this.currentNode)continue;const n=this._getNodeBounds(e);t.rects.push({center:{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2},width:n.maxX-n.minX,height:n.maxY-n.minY,fill:"rgba(0, 0, 0, 0.08)",stroke:"rgba(0, 0, 0, 0.2)",label:e.capacityMeshNodeId})}if(this.lastNode){const e=this._getNodeBounds(this.lastNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 0, 255, 0.6)"})}if(this.currentNode){const e=this._getNodeBounds(this.currentNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 200, 0, 0.6)"})}for(const e of this.unsolvedNodes){const n=new Map;for(const t of e.portPoints)n.has(t.connectionName)||n.set(t.connectionName,[]),n.get(t.connectionName).push({x:t.x,y:t.y});for(const[e,s]of n)s.length<2||t.lines.push({points:s.map(t=>({x:t.x,y:t.y})),label:e,strokeColor:"gray",strokeWidth:this.traceWidth})}for(const e of this.routes){const n=Wn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:In(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});const s=e.route;for(let e=0;e<s.length;e++){const n=s[e],o=0===e,i=e===s.length-1,r=!o&&!i;let a;a=o?"start":i?"end":`M${e}`,t.points.push({x:n.x,y:n.y,label:a,color:r?"orange":"blue"})}}for(const e of this.routesInProgress){const{startPoint:n,endPoint:s,movablePoints:o,connectionName:i}=e,r=this.colorMap[i]??"gray",a=[{x:n.x,y:n.y}];1===o.length?a.push({x:o[0].x,y:o[0].y}):2===o.length?(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[1].x,y:o[1].y})):3===o.length&&(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[2].x,y:o[2].y}),a.push({x:o[1].x,y:o[1].y})),a.push({x:s.x,y:s.y}),t.lines.push({points:a,label:i,strokeColor:r,strokeWidth:this.traceWidth}),t.points.push({x:n.x,y:n.y,label:"start",color:"blue"});for(let e=0;e<o.length;e++){const n=o[e];if(t.points.push({x:n.x,y:n.y,label:`M${e+1}`,color:"orange"}),void 0!==n.forceX&&void 0!==n.forceY){if(Math.sqrt(n.forceX*n.forceX+n.forceY*n.forceY)>.001){const s=5;t.lines.push({points:[{x:n.x,y:n.y},{x:n.x+n.forceX*s,y:n.y+n.forceY*s}],strokeColor:"red",strokeWidth:.02,label:`F${e+1}`});const o=.05,i=n.x+n.forceX*s,r=n.y+n.forceY*s,a=Math.atan2(n.forceY,n.forceX);t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a-Math.PI/6),y:r-o*Math.sin(a-Math.PI/6)}],strokeColor:"red",strokeWidth:.02}),t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a+Math.PI/6),y:r-o*Math.sin(a+Math.PI/6)}],strokeColor:"purple",strokeWidth:.02})}}}t.points.push({x:s.x,y:s.y,label:"end",color:"blue"})}return t}},Vd=({connMap:t,connectionsWithResults:e,inputNodes:n,obstacles:s})=>{const o=s.filter(t=>t.offBoardConnectsTo?.length);if(0===o.length)return;const i=new An({});i.addConnections(o.map((t,e)=>[t.obstacleId??`__obs${e}`,...t.offBoardConnectsTo??[]]));const r=new Map(n.map(t=>[t.capacityMeshNodeId,t]));for(const n of e){if(!n.path)continue;const e=n.connection.rootConnectionName??n.connection.name,s=new Set;for(const t of n.path){const e=r.get(t.currentNodeId);if(e?._offBoardConnectionId&&s.add(e._offBoardConnectionId),t.throughNodeId){const e=r.get(t.throughNodeId);e?._offBoardConnectionId&&s.add(e._offBoardConnectionId)}}for(const n of s){const s=i.getIdsConnectedToNet(n);s?.length&&t.addConnections([[e,...s]])}}};function Gd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Zd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline2"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceKeepoutSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Gd("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Gd("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Gd("relateNodesToOffBoardConnections",Xd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),Gd("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Gd("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Gd("portPointPathingSolver",zh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:100*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!1,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Vd({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),Gd("multiSectionPortPointOptimizer",Fh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints}]}),Gd("highDensitySolver",Ud,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,connMap:t.connMap}]),Gd("highDensityStitchSolver",Qh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Gd("traceSimplificationSolver",_l,t=>[{hdRoutes:t.highDensityStitchSolver?.mergedHdRoutes??t.highDensitySolver?.routes??t.highDensityRouteSolver?.routes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Gd("traceKeepoutSolver",Yd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??[],obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}]),Gd("traceWidthSolver",Cl,t=>[{hdRoutes:t.traceKeepoutSolver?.redrawnHdRoutes??[],connection:t.srj.connections,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.offboardPathFragmentSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensitySolver?.visualize(),p=this.simpleHighDensityRouteSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),m=this.traceSimplificationSolver?.visualize(),g=this.traceKeepoutSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,r,a,c,h,l,d?jn(b,d):null,u?jn(b,u):null,p?jn(b,p):null,f,m,g,y,this.solved?jn(b,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`,i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},qd=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver2"}unsolvedRoutes;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Map;for(const e of t.connectionPathResults)n.set(e.connection.name,e);const s=new Map;for(const e of t.hdRoutes){const t=s.get(e.connectionName);t?t.push(e):s.set(e.connectionName,[e])}this.unsolvedRoutes=[];for(const[e,o]of s.entries()){const s=t.connections.find(t=>t.name===e);if(!s)continue;const i=n.get(e);let r=[];i?.path&&(r=i.path.map(t=>t.currentNodeId));const a={...s.pointsToConnect[0],z:Rn(Tn(s.pointsToConnect[0]),t.layerCount)},c={...s.pointsToConnect[1],z:Rn(Tn(s.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:e,hdRoutes:o,nodeOrder:r,start:a,end:c})}this.MAX_ITERATIONS=1e5}_step(){const t=this.unsolvedRoutes.pop();if(!t)return void(this.solved=!0);const e=this.stitchOrderedRoutes(t);this.mergedHdRoutes.push(e)}stitchOrderedRoutes(t){const{connectionName:e,hdRoutes:n,nodeOrder:s,start:o,end:i}=t;if(0===n.length)return{connectionName:e,traceThickness:this.defaultTraceThickness,viaDiameter:this.defaultViaDiameter,route:[o,i],vias:[],jumpers:[]};let r;r=s.length>0?this.orderRoutesByNodePath(n,s,o,e):this.orderRoutesByProximity(n,o);const a=[],c=[],h=[];a.push({x:o.x,y:o.y,z:o.z});for(let t=0;t<r.length;t++){const e=r[t],n=a[a.length-1],s=e.route[0],o=e.route[e.route.length-1],i=k(n,s),l=k(n,o),d=Math.min(i,l);if(t>0&&d>1)continue;let u;u=i<=l?[...e.route]:[...e.route].reverse();const p=.001;u.length>0&&k(n,u[0])<p&&(u=u.slice(1)),a.push(...u),c.push(...e.vias),e.jumpers&&h.push(...e.jumpers)}const l=k(a[a.length-1],i);return l>.001&&l<5&&a.push({x:i.x,y:i.y,z:i.z}),{connectionName:e,rootConnectionName:n[0]?.rootConnectionName,traceThickness:n[0]?.traceThickness??this.defaultTraceThickness,viaDiameter:n[0]?.viaDiameter??this.defaultViaDiameter,route:a,vias:c,jumpers:h}}orderRoutesByNodePath(t,e,n,s){if(0===t.length)return[];const o=new Set(t);let i=null,r=1/0;for(const t of o){const e=t.route[0],s=t.route[t.route.length-1],o=Math.min(k(n,e),k(n,s));o<r&&(r=o,i=t)}if(!i)return[];o.delete(i);const a=i.route[0],c=i.route[i.route.length-1];let h,l;k(n,a)<=k(n,c)?(h=a,l=c):(h=c,l=a);const d=(t,e)=>{let n=0;for(const s of o){if(s===e)continue;const o=s.route[0],i=s.route[s.route.length-1];(k(t,o)<10||k(t,i)<10)&&n++}return n},u=[i];let p=l;for(;o.size>0;){let t=null,e=1/0,n=-1;for(const s of o){const o=s.route[0],i=s.route[s.route.length-1],r=k(p,o),a=k(p,i),c=Math.min(r,a);if(c>=10)continue;const h=d(r<=a?i:o,s),l=0===h,u=0===n,f=c-e;let m=!1;m=null===t||(!!(!l&&u&&f<5)||!(l&&!u&&f>-5)&&c<e),m&&(e=c,t=s,n=h)}if(!t)break;{u.push(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const f=[];for(p=h;o.size>0;){let t=null,e=1/0,s=-1;const i=k(p,n);for(const r of o){const o=r.route[0],a=r.route[r.route.length-1],c=k(p,o),h=k(p,a),l=Math.min(c,h);if(l>=10)continue;const u=c<=h?a:o;if(k(u,n)>i+2)continue;const f=d(u,r),m=0===f,g=0===s,y=l-e;let x=!1;x=null===t||(!!(!m&&g&&y<5)||!(m&&!g&&y>-5)&&l<e),x&&(e=l,t=r,s=f)}if(!t)break;{f.unshift(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const m=[...f,...u];if(o.size>0){const e=[...o].map(t=>{const e=t.route[0],n=t.route[t.route.length-1];return`start=(${e.x.toFixed(2)},${e.y.toFixed(2)}) end=(${n.x.toFixed(2)},${n.y.toFixed(2)})`});console.warn(`[StitchSolver] Skipped ${o.size} routes for connection ${t[0]?.connectionName??"?"}, skipped routes: ${e.join("; ")}`)}return m}orderRoutesByProximity(t,e){const n=new Set(t),s=[];let o=e;for(;n.size>0;){let t=null,e=1/0,i=!1;for(const s of n){const n=s.route[0],r=s.route[s.route.length-1],a=k(o,n),c=k(o,r);a<e&&(e=a,t=s,i=!1),c<e&&(e=c,t=s,i=!0)}if(!t)break;{s.push(t),n.delete(t);const e=t.route[0],r=t.route[t.route.length-1];o=i?e:r}}return s}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 2"};for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?In(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?In(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Gh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End`});for(let s=0;s<e.hdRoutes.length;s++){const o=e.hdRoutes[s];if(o.route.length>1&&t.lines?.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:In(n,.5),strokeDash:"10 5",label:`segment ${s}`}),o.jumpers&&o.jumpers.length>0){const e=Gh(o.jumpers,{color:n,label:o.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},Jd=Object.create,Kd=Object.defineProperty,Qd=Object.getOwnPropertyDescriptor,tu=Object.getOwnPropertyNames,eu=Object.getPrototypeOf,nu=Object.prototype.hasOwnProperty,su=(t,e)=>function(){return e||(0,t[tu(t)[0]])((e={exports:{}}).exports,e),e.exports},ou=(t,e,n)=>(n=null!=t?Jd(eu(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of tu(e))nu.call(t,o)||o===n||Kd(t,o,{get:()=>e[o],enumerable:!(s=Qd(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Kd(n,"default",{value:t,enumerable:!0}),t)),iu=su({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),ru=su({"node_modules/kind-of/index.js"(t,e){var n=iu(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),au=su({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),cu=su({"node_modules/deep-rename-keys/index.js"(t,e){var n=ru(),s=au();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),hu=su({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),lu=su({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=hu(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),du=su({"node_modules/xml-reader/dist/reader.js"(t,e){var n=hu(),s=lu(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:uu,sin:pu,PI:fu}=Math,{tan:mu}=Math,gu=(ou(cu()),ou(du()),class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.constructor.name} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.constructor.name} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}}),yu=t=>t?`hsl(${(t=>{let e=0;for(let n=0;n<t.length;n++)e=779*t.charCodeAt(n)+((e<<5)-e);return e})(t)%360}, 100%, 50%)`:"rgba(0, 0, 0, 0.5)",xu=t=>[[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY}],[{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY}],[{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],[{x:t.minX,y:t.maxY},{x:t.minX,y:t.minY}]];function vu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=s-n,a=i-o,c=1e-6;return Math.abs(t.y-i)<c?t.x-n:Math.abs(t.x-s)<c?r+(i-t.y):Math.abs(t.y-o)<c?r+a+(s-t.x):Math.abs(t.x-n)<c?2*r+a+(t.y-o):0}function bu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=1e-6,a=Math.abs(t.y-i)<r,c=Math.abs(t.y-o)<r,h=Math.abs(t.x-s)<r,l=Math.abs(t.x-n)<r;if(a&&h)return{x:-Math.SQRT1_2,y:-Math.SQRT1_2};if(a&&l)return{x:Math.SQRT1_2,y:-Math.SQRT1_2};if(c&&h)return{x:-Math.SQRT1_2,y:Math.SQRT1_2};if(c&&l)return{x:Math.SQRT1_2,y:Math.SQRT1_2};if(a)return{x:0,y:-1};if(c)return{x:0,y:1};if(h)return{x:-1,y:0};if(l)return{x:1,y:0};const d=(o+i)/2,u=(n+s)/2-t.x,p=d-t.y,f=Math.hypot(u,p);return f>0?{x:u/f,y:p/f}:{x:0,y:-1}}function Pu(t,e,n,s,o,i,r,a,c,h){for(let l=0;l<=h;l++){const d=l/h,u=1-d,p=u*u,f=p*u,m=d*d,g=m*d,y=2*l;c[y]=f*t+3*p*d*n+3*u*m*o+g*r,c[y+1]=f*e+3*p*d*s+3*u*m*i+g*a}}function Su(t,e,n,s,o){const i=[];for(let r=0;r<=o;r++){const a=r/o,c=1-a,h=c*c,l=h*c,d=a*a,u=d*a;i.push({x:l*t.x+3*h*a*e.x+3*c*d*n.x+u*s.x,y:l*t.y+3*h*a*e.y+3*c*d*n.y+u*s.y})}return i}function Mu(t,e,n,s,o,i){const r=o-n,a=i-s,c=r*r+a*a;if(0===c){const o=t-n,i=e-s;return o*o+i*i}const h=Math.max(0,Math.min(1,((t-n)*r+(e-s)*a)/c)),l=t-(n+h*r),d=e-(s+h*a);return l*l+d*d}function Nu(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)?0:Math.min(Mu(t,e,o,i,r,a),Mu(n,s,o,i,r,a),Mu(o,i,t,e,n,s),Mu(r,a,t,e,n,s))}function Iu(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)}function _u(t,e,n,s,o){const i=t=>(t%o+o)%o,r=i(t),a=i(e),c=i(n),h=i(s),[l,d]=r<a?[r,a]:[a,r];return c>l&&c<d&&h>l&&h<d}function Cu(t,e){let n=1/0,s=-1/0,o=1/0,i=-1/0;for(let r=0;r<e;r++){const e=t[2*r],a=t[2*r+1];e<n&&(n=e),e>s&&(s=e),a<o&&(o=a),a>i&&(i=a)}return{minX:n,maxX:s,minY:o,maxY:i}}var Tu=class extends gu{constructor(t){super(),this.problem=t;for(const t of this.problem.obstacles)t.outerSegments=xu(t);this.precomputeObstacles()}outputTraces=[];traces=[];optimizationStep=0;maxOptimizationSteps=100;sampledPoints=[];traceBounds=[];obstacleSegments=new Float64Array(0);obstacleNetworkIds=[];numObstacleSegments=0;collisionPairs=[];lastCost=1/0;stagnantSteps=0;effectiveTraceToTraceSpacing=0;getConstructorParams(){return this.problem}precomputeObstacles(){const{obstacles:t}=this.problem;let e=0;for(const n of t)n.outerSegments&&(e+=n.outerSegments.length);this.obstacleSegments=new Float64Array(4*e),this.obstacleNetworkIds=[],this.numObstacleSegments=e;let n=0;for(const e of t)if(e.outerSegments)for(const t of e.outerSegments)this.obstacleSegments[n++]=t[0].x,this.obstacleSegments[n++]=t[0].y,this.obstacleSegments[n++]=t[1].x,this.obstacleSegments[n++]=t[1].y,this.obstacleNetworkIds.push(e.networkId)}initializeTraces(){const{bounds:t,waypointPairs:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=s-n,a=i-o,c=2*r+2*a,h=function(t){return{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}}(t),l=e.map((e,n)=>({pair:e,t1:vu(e.start,t),t2:vu(e.end,t),idx:n})),d=l.map(()=>[]),u=l.map(()=>[]);for(const t of l)for(const e of l)if(t.idx!==e.idx){if(t.pair.networkId&&e.pair.networkId&&t.pair.networkId===e.pair.networkId)continue;_u(e.t1,e.t2,t.t1,t.t2,c)&&(d[t.idx].push(e.idx),u[e.idx].push(t.idx))}const p=d.map(t=>t.length),f=Math.max(...p,1);this.traces=l.map(({pair:e,t1:n,t2:s,idx:o})=>{const i=bu(e.start,t),c=bu(e.end,t),l=Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),m=p[o]/f,g=(e.start.x+e.end.x)/2,y=(e.start.y+e.end.y)/2,x=l*(.25+.15*(1-Math.hypot(g-h.x,y-h.y)/Math.hypot(r/2,a/2)))*(1-.3*m),v=.05*Math.min(r,a),b=Math.max(v,x),P=Math.max(v,x);return{waypointPair:e,ctrl1:{x:e.start.x+b*i.x,y:e.start.y+b*i.y},ctrl2:{x:e.end.x+P*c.x,y:e.end.y+P*c.y},networkId:e.networkId,t1:n,t2:s,perpDir1:i,perpDir2:c,d1:b,d2:P,containedBy:d[o],contains:u[o]}}),this.sampledPoints=this.traces.map(()=>new Float64Array(12)),this.traceBounds=this.traces.map(()=>({minX:0,maxX:0,minY:0,maxY:0})),this.updateSampledTraces(),this.updateCollisionPairs()}updateSampledTraces(){for(let t=0;t<this.traces.length;t++){const e=this.traces[t];Pu(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=Cu(this.sampledPoints[t],6)}}updateSingleTraceSample(t){const e=this.traces[t];Pu(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=Cu(this.sampledPoints[t],6)}updateControlPointsFromDistances(t){const e=this.traces[t],{minX:n,maxX:s,minY:o,maxY:i}=this.problem.bounds,r=1e-6;let a=e.waypointPair.start.x+e.d1*e.perpDir1.x,c=e.waypointPair.start.y+e.d1*e.perpDir1.y,h=e.waypointPair.end.x+e.d2*e.perpDir2.x,l=e.waypointPair.end.y+e.d2*e.perpDir2.y;const d=e.waypointPair.start;Math.abs(d.x-n)<r&&(a=Math.max(a,n)),Math.abs(d.x-s)<r&&(a=Math.min(a,s)),Math.abs(d.y-o)<r&&(c=Math.max(c,o)),Math.abs(d.y-i)<r&&(c=Math.min(c,i));const u=e.waypointPair.end;Math.abs(u.x-n)<r&&(h=Math.max(h,n)),Math.abs(u.x-s)<r&&(h=Math.min(h,s)),Math.abs(u.y-o)<r&&(l=Math.max(l,o)),Math.abs(u.y-i)<r&&(l=Math.min(l,i)),a=Math.max(n,Math.min(s,a)),c=Math.max(o,Math.min(i,c)),h=Math.max(n,Math.min(s,h)),l=Math.max(o,Math.min(i,l)),e.ctrl1.x=a,e.ctrl1.y=c,e.ctrl2.x=h,e.ctrl2.y=l}updateCollisionPairs(){const t=this.effectiveTraceToTraceSpacing;this.collisionPairs=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX+t>=r.minX&&r.maxX+t>=i.minX&&i.maxY+t>=r.minY&&r.maxY+t>=i.minY&&this.collisionPairs.push([e,n])}}computeTotalCost(){const{preferredObstacleToTraceSpacing:t}=this.problem,e=this.effectiveTraceToTraceSpacing,n=e**2,s=t**2;let o=0;for(const[t,s]of this.collisionPairs){const i=this.sampledPoints[t],r=this.sampledPoints[s];for(let t=0;t<5;t++){const s=i[2*t],a=i[2*t+1],c=i[2*(t+1)],h=i[2*(t+1)+1];for(let t=0;t<5;t++){const i=Nu(s,a,c,h,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]);if(i<n){o+=(e-Math.sqrt(i))**2,i<1e-18&&(o+=20*n)}}}}for(let e=0;e<this.traces.length;e++){const n=this.traces[e],i=this.sampledPoints[e],r=this.traceBounds[e];for(let e=0;e<this.numObstacleSegments;e++){if(n.networkId&&this.obstacleNetworkIds[e]&&n.networkId===this.obstacleNetworkIds[e])continue;const a=4*e,c=this.obstacleSegments[a],h=this.obstacleSegments[a+1],l=this.obstacleSegments[a+2],d=this.obstacleSegments[a+3],u=Math.min(c,l),p=Math.max(c,l),f=Math.min(h,d),m=Math.max(h,d);if(!(r.maxX+t<u||p+t<r.minX||r.maxY+t<f||m+t<r.minY))for(let e=0;e<5;e++){const n=Nu(i[2*e],i[2*e+1],i[2*(e+1)],i[2*(e+1)+1],c,h,l,d);if(n<s){o+=(t-Math.sqrt(n))**2,n<1e-18&&(o+=20*s)}}}}return o}computeCostForTrace(t){const{preferredObstacleToTraceSpacing:e}=this.problem,n=this.effectiveTraceToTraceSpacing,s=n**2,o=e**2,i=this.traces[t],r=this.sampledPoints[t],a=this.traceBounds[t];let c=0;for(let e=0;e<this.traces.length;e++){if(e===t)continue;const o=this.traces[e];if(i.networkId&&o.networkId&&i.networkId===o.networkId)continue;const h=this.traceBounds[e];if(a.maxX+n<h.minX||h.maxX+n<a.minX||a.maxY+n<h.minY||h.maxY+n<a.minY)continue;const l=this.sampledPoints[e];for(let t=0;t<5;t++){const e=r[2*t],o=r[2*t+1],i=r[2*(t+1)],a=r[2*(t+1)+1];for(let t=0;t<5;t++){const r=Nu(e,o,i,a,l[2*t],l[2*t+1],l[2*(t+1)],l[2*(t+1)+1]);if(r<s){c+=(n-Math.sqrt(r))**2,r<1e-18&&(c+=20*s)}}}}for(let t=0;t<this.numObstacleSegments;t++){if(i.networkId&&this.obstacleNetworkIds[t]&&i.networkId===this.obstacleNetworkIds[t])continue;const n=4*t,s=this.obstacleSegments[n],h=this.obstacleSegments[n+1],l=this.obstacleSegments[n+2],d=this.obstacleSegments[n+3],u=Math.min(s,l),p=Math.max(s,l),f=Math.min(h,d),m=Math.max(h,d);if(!(a.maxX+e<u||p+e<a.minX||a.maxY+e<f||m+e<a.minY))for(let t=0;t<5;t++){const n=Nu(r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1],s,h,l,d);if(n<o){c+=(e-Math.sqrt(n))**2,n<1e-18&&(c+=20*o)}}}return c}tracesIntersect(t,e){const n=this.traces[t],s=this.traces[e],o=15,i=new Float64Array(32),r=new Float64Array(32);Pu(n.waypointPair.start.x,n.waypointPair.start.y,n.ctrl1.x,n.ctrl1.y,n.ctrl2.x,n.ctrl2.y,n.waypointPair.end.x,n.waypointPair.end.y,i,o),Pu(s.waypointPair.start.x,s.waypointPair.start.y,s.ctrl1.x,s.ctrl1.y,s.ctrl2.x,s.ctrl2.y,s.waypointPair.end.x,s.waypointPair.end.y,r,o);for(let t=0;t<o;t++){const e=i[2*t],n=i[2*t+1],s=i[2*(t+1)],a=i[2*(t+1)+1];for(let t=0;t<o;t++){if(Iu(e,n,s,a,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]))return!0}}return!1}findIntersectingPairs(){const t=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX<r.minX||r.maxX<i.minX||i.maxY<r.minY||r.maxY<i.minY||this.tracesIntersect(e,n)&&t.push([e,n])}return t}resolveIntersections(){const{bounds:t,preferredTraceToTraceSpacing:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=Math.min(s-n,i-o),a=.02*r,c=1.5*r,h=this.findIntersectingPairs();if(0===h.length)return 0;let l=0;for(const[t,n]of h){const s=this.traces[t],o=this.traces[n];if(!this.tracesIntersect(t,n))continue;let i,r;if(s.containedBy.includes(n))i=n,r=t;else if(o.containedBy.includes(t))i=t,r=n;else{(s.d1+s.d2)/2<(o.d1+o.d2)/2?(i=t,r=n):(i=n,r=t)}const h=this.traces[i],d=this.traces[r],u=h.d1,p=h.d2,f=d.d1,m=d.d2,g=2*e,y=[{innerMult:1,outerMult:0},{innerMult:0,outerMult:1},{innerMult:.5,outerMult:.5},{innerMult:2,outerMult:0},{innerMult:1,outerMult:1},{innerMult:3,outerMult:0},{innerMult:2,outerMult:1},{innerMult:4,outerMult:0}];let x=this.computeTotalCost(),v=null;for(const t of y)if(h.d1=u,h.d2=p,d.d1=f,d.d2=m,d.d1=Math.min(c,f+g*t.innerMult),d.d2=Math.min(c,m+g*t.innerMult),h.d1=Math.max(a,u-g*t.outerMult),h.d2=Math.max(a,p-g*t.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),!this.tracesIntersect(i,r)){const e=this.computeTotalCost();(null===v||e<x)&&(x=e,v=t)}v?(d.d1=Math.min(c,f+g*v.innerMult),d.d2=Math.min(c,m+g*v.innerMult),h.d1=Math.max(a,u-g*v.outerMult),h.d2=Math.max(a,p-g*v.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),l++):(h.d1=u,h.d2=p,d.d1=f,d.d2=m,this.updateControlPointsFromDistances(i),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(i),this.updateSingleTraceSample(r))}return l}optimizeStep(){const{bounds:t}=this.problem,{minX:e,maxX:n,minY:s,maxY:o}=t,i=Math.min(n-e,o-s),r=this.effectiveTraceToTraceSpacing,a=4*(1-this.optimizationStep/this.maxOptimizationSteps)+.5,c=.02*i,h=1.5*i,l=[];for(let t=0;t<this.traces.length;t++)l.push({idx:t,cost:this.computeCostForTrace(t)});l.sort((t,e)=>e.cost-t.cost);for(const{idx:t,cost:e}of l){if(0===e)continue;const n=this.traces[t],s=e>100?2:1,o=[a*s,1.5*a*s,.5*a];for(const s of o){const o=e>100?[s,-s,2*s,2*-s,3*s,3*-s,2*r,2*-r]:[s,-s,2*s,2*-s];let i=this.computeCostForTrace(t),a=n.d1,l=n.d2;const d=n.d1,u=n.d2;for(const e of o){n.d1=Math.max(c,Math.min(h,d+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const s=this.computeCostForTrace(t);s<i&&(i=s,a=n.d1,l=u),n.d1=d,this.updateControlPointsFromDistances(t),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const o=this.computeCostForTrace(t);o<i&&(i=o,a=d,l=n.d2),n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const r=this.computeCostForTrace(t);r<i&&(i=r,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u-e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const p=this.computeCostForTrace(t);p<i&&(i=p,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t)}if(n.d1=a,n.d2=l,this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t),i<.9*e)break}}this.optimizationStep%10==0&&this.updateCollisionPairs()}buildOutputTraces(){this.outputTraces=this.traces.map(t=>({waypointPair:t.waypointPair,points:Su(t.waypointPair.start,t.ctrl1,t.ctrl2,t.waypointPair.end,20),networkId:t.networkId}))}_step(){if(0===this.traces.length&&(this.effectiveTraceToTraceSpacing=3*this.problem.preferredTraceToTraceSpacing,this.initializeTraces(),this.lastCost=this.computeTotalCost(),this.stagnantSteps=0),this.optimizationStep<this.maxOptimizationSteps){const t=3,e=t+(1-t)*(this.optimizationStep/this.maxOptimizationSteps);if(this.effectiveTraceToTraceSpacing=this.problem.preferredTraceToTraceSpacing*e,this.optimizeStep(),this.optimizationStep++,this.optimizationStep%10==0){this.resolveIntersections()>0&&this.updateCollisionPairs()}const n=this.computeTotalCost();if(0===n)this.optimizationStep=this.maxOptimizationSteps;else if(n>=.99*this.lastCost){if(this.stagnantSteps++,this.stagnantSteps>10){this.resolveIntersections()>0?(this.updateCollisionPairs(),this.stagnantSteps=0):this.stagnantSteps>15&&(this.optimizationStep=this.maxOptimizationSteps)}}else this.stagnantSteps=0;this.lastCost=n}this.optimizationStep>=this.maxOptimizationSteps&&(this.resolveIntersections(),this.buildOutputTraces(),this.solved=!0)}visualize(){return this.traces.length>0&&this.buildOutputTraces(),((t,e=[])=>{const n={arrows:[],circles:[],lines:[],rects:[],coordinateSystem:"cartesian",points:[],texts:[],title:"Curvy Trace Problem"};n.lines.push({points:[{x:t.bounds.minX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.minY}],strokeColor:"rgba(0, 0, 0, 0.1)"});for(const e of t.waypointPairs)n.points.push({...e.start,label:`start ${e.networkId??""}`,color:yu(e.networkId)}),n.points.push({...e.end,label:`end ${e.networkId??""}`,color:yu(e.networkId)});for(const e of t.obstacles)n.rects.push({center:e.center,width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(128, 128, 128, 0.3)",stroke:"rgba(128, 128, 128, 0.8)",label:`netId: ${e.networkId}`});for(const t of e)n.lines.push({points:t.points,strokeColor:yu(t.networkId)});return n})(this.problem,this.outputTraces)}},Eu=class extends Ln{getSolverName(){return"CurvyIntraNodeSolver"}nodeWithPortPoints;colorMap;traceWidth;viaDiameter;adjacentObstacles;routes=[];curvyTraceSolver;phase="initializing";constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaDiameter=t.viaDiameter??.3,this.adjacentObstacles=t.adjacentObstacles??[],this.MAX_ITERATIONS=1e3}_step(){switch(this.phase){case"initializing":this._initializeCurvySolver();break;case"solving":this._stepCurvySolver();break;case"done":this.solved=!0}}_initializeCurvySolver(){const t=this.nodeWithPortPoints,e={minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2},n=new Map;for(const e of t.portPoints)n.has(e.connectionName)||n.set(e.connectionName,[]),n.get(e.connectionName).push(e);const s=[];for(const[t,e]of n){if(e.length<2)continue;const n=e[0],o=e[e.length-1];s.push({start:{x:n.x,y:n.y},end:{x:o.x,y:o.y},networkId:t})}if(0===s.length)return void(this.phase="done");const o={bounds:e,waypointPairs:s,obstacles:this.adjacentObstacles.map(t=>({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},networkId:t.networkId})),preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth};this.curvyTraceSolver=new Tu(o),this.phase="solving"}_stepCurvySolver(){this.curvyTraceSolver?(this.activeSubSolver=this.curvyTraceSolver,this.curvyTraceSolver.step(),this.curvyTraceSolver.solved?(this._convertOutputTraces(),this.phase="done"):this.curvyTraceSolver.failed&&(this.error=this.curvyTraceSolver.error,this.failed=!0)):this.phase="done"}_convertOutputTraces(){if(!this.curvyTraceSolver)return;const t=this.nodeWithPortPoints,e=new Map;for(const n of t.portPoints){const t=n.connectionName;e.has(t)||e.set(t,{connectionName:n.connectionName,rootConnectionName:n.rootConnectionName,z:n.z})}for(const t of this.curvyTraceSolver.outputTraces){const n=t.networkId??"",s=e.get(n);if(!s)continue;const o={connectionName:s.connectionName,rootConnectionName:s.rootConnectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:t.points.map(t=>({x:t.x,y:t.y,z:s.z})),vias:[]};this.routes.push(o)}}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:this.adjacentObstacles}}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints;t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(0, 200, 0, 0.1)",stroke:"rgba(0, 200, 0, 0.5)",label:e.capacityMeshNodeId});for(const e of this.adjacentObstacles)t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(255, 0, 0, 0.1)",stroke:"rgba(255, 0, 0, 0.3)",label:`obstacle: ${e.networkId??""}`});if(this.curvyTraceSolver){const e=this.curvyTraceSolver.visualize();e.lines&&t.lines.push(...e.lines),e.points&&t.points.push(...e.points),e.rects&&t.rects.push(...e.rects),e.circles&&t.circles.push(...e.circles)}for(const e of this.routes){const n=this.colorMap[e.connectionName]??"gray";t.lines.push({points:e.route.map(t=>({x:t.x,y:t.y})),strokeColor:n,strokeWidth:this.traceWidth,label:e.connectionName})}for(const n of e.portPoints){const e=this.colorMap[n.connectionName]??"gray";t.points.push({x:n.x,y:n.y,color:e,label:n.connectionName})}return t}},wu=Object.create,Ru=Object.defineProperty,Ou=Object.getOwnPropertyDescriptor,Au=Object.getOwnPropertyNames,zu=Object.getPrototypeOf,Du=Object.prototype.hasOwnProperty,Lu=(t,e)=>function(){return e||(0,t[Au(t)[0]])((e={exports:{}}).exports,e),e.exports},Fu=(t,e,n)=>(n=null!=t?wu(zu(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Au(e))Du.call(t,o)||o===n||Ru(t,o,{get:()=>e[o],enumerable:!(s=Ou(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Ru(n,"default",{value:t,enumerable:!0}),t)),Yu=Lu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),Xu=Lu({"node_modules/kind-of/index.js"(t,e){var n=Yu(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),ku=Lu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),$u=Lu({"node_modules/deep-rename-keys/index.js"(t,e){var n=Xu(),s=ku();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),Bu=Lu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),ju=Lu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=Bu(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),Wu=Lu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=Bu(),s=ju(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:Hu,sin:Uu,PI:Vu}=Math,{tan:Gu}=Math;Fu($u()),Fu(Wu());function Zu(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var qu=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Ju(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Ku=class extends qu{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(Zu(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(Zu(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(Zu(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Qu=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),tp=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||Qu(e,n,t)>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||Qu(t,n,e)>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},ep=t=>void 0!==t,np=class extends qu{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(ep)),hulls:n.cells.map(t=>tp(t,n.pts).map(t=>n.pts[t]).filter(ep))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},sp=(t,e,n)=>{const s=Math.cos(n.ccwRotation),o=Math.sin(n.ccwRotation);return{x:n.center.x+t*s-e*o,y:n.center.y+t*o+e*s}},op=(t,e=[],n,s=[])=>{const o=[],{minX:i,maxX:r,minY:a,maxY:c}=t;o.push({x:i,y:a},{x:r,y:a},{x:r,y:c},{x:i,y:c});for(let t=1;t<10;t++){const e=t/10;o.push({x:i+e*(r-i),y:a}),o.push({x:r,y:a+e*(c-a)}),o.push({x:r-e*(r-i),y:c}),o.push({x:i,y:c-e*(c-a)})}for(const t of e){const e=t.diameter/2+n;for(let n=0;n<24;n++){const s=2*Math.PI*n/24;o.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of s){const e=t.width/2+n,s=t.height/2+n,i=Math.max(2,Math.ceil(Math.max(2*e,2*s)/20));for(let n=0;n<i;n++){const r=n/i;o.push(sp(2*r*e-e,-s,t)),o.push(sp(e,2*r*s-s,t)),o.push(sp(e-2*r*e,s,t)),o.push(sp(-e,s-2*r*s,t))}}return o.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},ip=class extends qu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[];this.output={pts:op(this.input.bounds,t,this.input.clearance,e)},this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},rp=(t,e,n)=>{const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-10)return Math.hypot(t.x-e.x,t.y-e.y);let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;return r=Math.max(0,Math.min(1,r)),Math.hypot(t.x-e.x-r*s,t.y-e.y-r*o)},ap=(t,e)=>{if(t.length<=3)return 0;const n=tp(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,rp(t,n,s)))}i=Math.max(i,r)}return i},cp=(t,e)=>t<e?1e5*t+e:1e5*e+t,hp=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(cp(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(cp(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(cp(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},lp=(t,e)=>t<e?1e5*t+e:1e5*e+t,dp=class extends qu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=((t,e,n)=>{if(!t.length)return{cells:[],depths:[]};const s=t.map(([t,n,s])=>{const o=e[t],i=e[n],r=e[s];return o&&i&&r&&Qu(o,i,r)<0?[t,s,n]:[t,n,s]});let o=!0,i=0;for(;o&&i++<800;){o=!1;const t=new Map,i=s.map(()=>new Set);for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let s=0;s<n.length;s++){const o=n[s],r=n[(s+1)%n.length];if(void 0===o||void 0===r)continue;const a=lp(o,r);if(t.has(a)){const n=t.get(a);void 0!==n&&(i[e]?.add(n),i[n]?.add(e))}else t.set(a,e)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<s.length;t++){const o=i[t];if(o)for(const i of o){if(i<=t)continue;const o=hp(s[t]??[],s[i]??[]);if(!o)continue;const l=ap(o,e);l<=n+1e-6&&l<h&&(h=l,r=t,a=i,c=o)}}if(r<0||a<0||!c)break;s[r]=c,s.splice(a,1),o=!0}const r=s.map(t=>ap(t,e));return{cells:s,depths:r}})(this.input.validTris,this.input.pts,this.input.concavityTolerance);this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},up=(t,e,n)=>{const s=2*(t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y));if(Math.abs(s)<1e-10)return{x:0,y:0,r2:1e18};const o=t.x*t.x+t.y*t.y,i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=(o*(e.y-n.y)+i*(n.y-t.y)+r*(t.y-e.y))/s,c=(o*(n.x-e.x)+i*(t.x-n.x)+r*(e.x-t.x))/s;return{x:a,y:c,r2:(t.x-a)**2+(t.y-c)**2}},pp=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),fp=(t,e,n,s=[],o,i=[])=>t.filter(([t,r,a])=>{const c=e[t],h=e[r],l=e[a];if(!c||!h||!l)return!1;return((t,e,n,s=[],o,i=[])=>{const{minX:r,maxX:a,minY:c,maxY:h}=n;if(t<r-.1||t>a+.1||e<c-.1||e>h+.1)return!1;for(const n of s){const s=n.diameter/2+o;if((t-n.center.x)**2+(e-n.center.y)**2<s*s-.1)return!1}for(const n of i){const s=n.width/2+o,i=n.height/2+o,r=t-n.center.x,a=e-n.center.y,c=Math.cos(n.ccwRotation),h=Math.sin(n.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<i-.1)return!1}return!0})((c.x+h.x+l.x)/3,(c.y+h.y+l.y)/3,n,s,o,i)}),mp=class extends qu{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:up(h,l,d)}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&pp(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:up(e,n,t)})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts),s=fp(n,this.input.pts,this.input.bounds,t,this.input.clearance,e);this.output={pts:this.input.pts,validTris:s},this.stats={candidateTriangles:n.length,validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},gp=class extends Ku{pipelineDef=[Ju("generatePoints",ip,t=>[t.inputProblem]),Ju("triangulate",mp,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,clearance:t.inputProblem.clearance}]}),Ju("mergeCells",dp,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),Ju("buildRegions",np,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},yp=1e-9,xp=(t,e)=>{const n=[Ap(t)],s=[];let o=e.maxSplitsPerRegion??32;for(;n.length>0;){const t=n.pop();if(!t)continue;if(t.length<4){s.push(t);continue}const i=vp(t,e);if(!i||o<=0){s.push(t);continue}const[r,a]=Pp(t,i.i,i.j);o-=1,n.push(r,a)}return s},vp=(t,e)=>{const n=Mp(t);if(!n)return null;const{triangles:s}=n,o=Ep(t);if(o<=yp)return null;const i=Math.sqrt(o),r=s.map(e=>wp(t[e[0]],t[e[1]],t[e[2]]));let a=null;for(const c of n.internalEdges){const{i:h,j:l,triA:d,triB:u}=c,p=Rp(t[h],t[l])/i;if(p>e.maxNeckRatio)continue;const f=bp(d,u,s.length,n.triangleAdjacency,r),m=o-f,g=Math.min(f,m)/o;if(g<e.minSplitBalanceRatio)continue;const y=p/Math.max(g,yp);(!a||y<a.score)&&(a={i:h,j:l,score:y})}return a?{i:a.i,j:a.j}:null},bp=(t,e,n,s,o)=>{const i=new Array(n).fill(!1),r=[t];i[e]=!0;let a=0;for(;r.length>0;){const t=r.pop();if(void 0===t||i[t])continue;i[t]=!0,a+=o[t]??0;const e=s[t]??[];for(const t of e)i[t]||r.push(t)}return a},Pp=(t,e,n)=>[Sp(t,e,n),Sp(t,n,e)],Sp=(t,e,n)=>{const s=[],o=t.length;let i=e;for(s.push(t[i]);i!==n;)i=(i+1)%o,s.push(t[i]);return Ap(s)},Mp=t=>{const e=t.length;if(e<3)return null;const n=new Set;for(let t=0;t<e;t++){const s=(t+1)%e;n.add(Op(t,s))}const s=Np(t);if(!s||0===s.length)return null;const o=new Map;s.forEach((t,e)=>{for(let n=0;n<3;n++){const s=t[n],i=t[(n+1)%3],r=Op(s,i),a=o.get(r);a?a.push(e):o.set(r,[e])}});const i=Array.from({length:s.length},()=>[]),r=[];for(const[t,e]of o.entries()){if(n.has(t))continue;if(2!==e.length)continue;const[s,o]=t.split("_"),a=Number(s),c=Number(o),h=e[0],l=e[1];r.push({i:a,j:c,triA:h,triB:l});const d=i[h],u=i[l];d&&d.push(l),u&&u.push(h)}return{triangles:s,internalEdges:r,triangleAdjacency:i}},Np=t=>{const e=t.length;if(e<3)return null;const n=Math.sign(Tp(t));if(0===n)return null;const s=[...Array(e).keys()];n<0&&s.reverse();const o=[];let i=0;for(;s.length>3&&i<e*e;){let e=!1;for(let n=0;n<s.length;n++){const i=s[(n-1+s.length)%s.length],r=s[n],a=s[(n+1)%s.length];if(void 0===i||void 0===r||void 0===a)continue;const c=t[i],h=t[r],l=t[a];if(!c||!h||!l)continue;if(!Ip(c,h,l))continue;let d=!1;for(const e of s){if(e===i||e===r||e===a)continue;const n=t[e];if(n&&_p(n,c,h,l)){d=!0;break}}if(!d){o.push([i,r,a]),s.splice(n,1),e=!0;break}}if(!e)return null;i+=1}if(3===s.length){const[t,e,n]=s;void 0!==t&&void 0!==e&&void 0!==n&&o.push([t,e,n])}return o},Ip=(t,e,n)=>Cp(t,e,n)>yp,_p=(t,e,n,s)=>{const o=Cp(e,n,t),i=Cp(n,s,t),r=Cp(s,e,t);return o>=-1e-9&&i>=-1e-9&&r>=-1e-9},Cp=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Tp=t=>{let e=0;for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];s&&o&&(e+=s.x*o.y-o.x*s.y)}return e/2},Ep=t=>Math.abs(Tp(t)),wp=(t,e,n)=>Math.abs(Cp(t,e,n))/2,Rp=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),Op=(t,e)=>t<e?`${t}_${e}`:`${e}_${t}`,Ap=t=>{if(t.length<2)return t;const e=t[0],n=t[t.length-1];return e&&n&&e.x===n.x&&e.y===n.y?t.slice(0,-1):t},zp={pattern:"grid",pitchX:2.2,pitchY:1.8,staggerAxis:"x",staggerOffset:1.1,staggerOffsetX:1.1,padWidth:.9,padHeight:1,padGap:.35,viaDiameter:.3,clearance:.2,concavityTolerance:.3,boundsPadding:1.2,orientation:"horizontal",portSpacing:.25,maxNeckRatio:0,minSplitBalanceRatio:.2},Dp=(t,e)=>{let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)for(const t of r.padCenters){const r="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,a="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2;t.x-r<n&&(n=t.x-r),t.y-a<s&&(s=t.y-a),t.x+r>o&&(o=t.x+r),t.y+a>i&&(i=t.y+a)}return{minX:n-e.boundsPadding,minY:s-e.boundsPadding,maxX:o+e.boundsPadding,maxY:i+e.boundsPadding}},Lp=t=>"staggered"===t.pattern?(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++){const a="x"===t.staggerAxis&&r%2==1?t.staggerOffset:0;for(let c=0;c<t.cols;c++){const h="y"===t.staggerAxis&&c%2==1?t.staggerOffset:0,l={x:o+c*t.pitchX+a,y:i+r*t.pitchY+h},d="horizontal"===t.orientation?{x:l.x-s,y:l.y}:{x:l.x,y:l.y-s},u="horizontal"===t.orientation?{x:l.x+s,y:l.y}:{x:l.x,y:l.y+s};e.push({jumperId:`jumper_r${r}_c${c}`,center:l,orientation:t.orientation,padCenters:[d,u]}),n.push({center:d,diameter:t.viaDiameter},{center:u,diameter:t.viaDiameter})}}return{jumpers:e,vias:n,bounds:Dp(e,t)}})(t):(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++)for(let a=0;a<t.cols;a++){const c={x:o+a*t.pitchX,y:i+r*t.pitchY},h="horizontal"===t.orientation?{x:c.x-s,y:c.y}:{x:c.x,y:c.y-s},l="horizontal"===t.orientation?{x:c.x+s,y:c.y}:{x:c.x,y:c.y+s},d=`jumper_r${r}_c${a}`;e.push({jumperId:d,center:c,orientation:t.orientation,padCenters:[h,l]}),n.push({center:h,diameter:t.viaDiameter},{center:l,diameter:t.viaDiameter})}return{jumpers:e,vias:n,bounds:{minX:o-s-t.padWidth/2-t.boundsPadding,maxX:o+(t.cols-1)*t.pitchX+s+t.padWidth/2+t.boundsPadding,minY:i-s-t.padHeight/2-t.boundsPadding,maxY:i+(t.rows-1)*t.pitchY+s+t.padHeight/2+t.boundsPadding}}})(t),Fp=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Yp=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],Xp=(t,e,n)=>Math.abs(t-e)<=n,kp=(t,e,n)=>Xp(t.x,e.x,n)&&Xp(t.y,e.y,n),$p=t=>t.map((t,e)=>{const n=(t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t)i.x<e&&(e=i.x),i.y<n&&(n=i.y),i.x>s&&(s=i.x),i.y>o&&(o=i.y);return{minX:e,minY:n,maxX:s,maxY:o}})(t);return{regionId:`top_${e}`,ports:[],d:{bounds:n,center:Fp(n),polygon:t,isPad:!1}}}),Bp=t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y;return Math.hypot(e,n)},jp=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),Wp=(t,e,n)=>{const s=[];if(!t.d.polygon||!e.d.polygon)return s;for(let o=0;o<t.d.polygon.length;o++){const i=t.d.polygon[o],r=t.d.polygon[(o+1)%t.d.polygon.length];if(i&&r)for(let t=0;t<e.d.polygon.length;t++){const o=e.d.polygon[t],a=e.d.polygon[(t+1)%e.d.polygon.length];if(!o||!a)continue;const c=Gp({start:i,end:r},{start:o,end:a},n);if(!c)continue;s.some(t=>Vp(t,c,n))||s.push(c)}}return s},Hp=(t,e)=>{const n=[];for(const s of t){let t=s,o=!0;for(;o;){o=!1;for(let s=0;s<n.length;s++){const i=n[s];if(!i)continue;const r=Up(t,i,e);if(r){t=r,n.splice(s,1),o=!0;break}}}n.push(t)}return n},Up=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!Xp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!Xp(s*h-o*c,0,n)||!Xp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.min(p,f),g=Math.max(p,f),y=n/Math.sqrt(a);if(m>1+y||g<0-y)return null;const x=Math.min(0,m),v=Math.max(1,g);return{start:jp(t,x),end:jp(t,v)}},Vp=(t,e,n)=>kp(t.start,e.start,n)&&kp(t.end,e.end,n)||kp(t.start,e.end,n)&&kp(t.end,e.start,n),Gp=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!Xp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!Xp(s*h-o*c,0,n)||!Xp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.max(0,Math.min(p,f)),g=Math.min(1,Math.max(p,f));return g-m<=n/Math.sqrt(a)?null:{start:jp(t,m),end:jp(t,g)}},Zp=(t,e,n)=>{const s=Math.max(t.minX,e.minX),o=Math.min(t.maxX,e.maxX),i=Math.max(t.minY,e.minY),r=Math.min(t.maxY,e.maxY);return o<s-n||r<i-n?null:{minX:s,maxX:o,minY:i,maxY:r}},qp=t=>{const e=(t=>{const e=t.orientation??zp.orientation,n=t.staggerAxis??zp.staggerAxis,s=t.padWidth??zp.padWidth,o=t.padHeight??zp.padHeight,i=t.padGap??zp.padGap,r=t.clearance??zp.clearance,a=t.colSpacing??t.pitchX??zp.pitchX,c=t.rowSpacing??t.pitchY??zp.pitchY,h=(l=s,d=o,u=i,"horizontal"===e?{x:u+2*l,y:d}:{x:d,y:u+2*l});var l,d,u;const p=r,f=((t,e,n,s,o)=>"horizontal"===t?"x"===e?o+2*n:s:"x"===e?s:o+2*n)(e,n,s,o,i)/2,m=t.staggerOffset??t.staggerOffsetX??f,g={...zp,...t,orientation:e,staggerAxis:n,pitchX:Math.max(a,h.x+p),pitchY:Math.max(c,h.y+p),padWidth:s,padHeight:o,padGap:i,staggerOffset:m,staggerOffsetX:m,concavityTolerance:t.concavityTolerance??zp.concavityTolerance,clearance:r,portSpacing:t.portSpacing??zp.portSpacing,maxNeckRatio:t.maxNeckRatio??zp.maxNeckRatio,minSplitBalanceRatio:t.minSplitBalanceRatio??zp.minSplitBalanceRatio};if(g.cols<=0||g.rows<=0)throw new Error("rows and cols must be > 0");if(!Number.isFinite(g.portSpacing)||g.portSpacing<=0)throw new Error("portSpacing must be > 0");if(!Number.isFinite(g.maxNeckRatio)||g.maxNeckRatio<0)throw new Error("maxNeckRatio must be >= 0");if(!Number.isFinite(g.minSplitBalanceRatio)||g.minSplitBalanceRatio<0||g.minSplitBalanceRatio>.5)throw new Error("minSplitBalanceRatio must be between 0 and 0.5");return g})(t),n=Lp(e),s="horizontal"===e.orientation?e.padWidth:e.padHeight,o="horizontal"===e.orientation?e.padHeight:e.padWidth,i=n.jumpers.flatMap(t=>t.padCenters.map(t=>({center:t,width:s,height:o,ccwRotation:0}))),r=new gp({bounds:n.bounds,rects:i,clearance:0,concavityTolerance:e.concavityTolerance});r.solve();const a=r.getOutput();if(!a)throw new Error(r.error??"ConvexRegionsSolver failed");const c=((t,e)=>{if(e.maxNeckRatio<=0)return t;const n=[];for(const s of t)n.push(...xp(s,e));return n})(a.regions,{maxNeckRatio:e.maxNeckRatio,minSplitBalanceRatio:e.minSplitBalanceRatio}),h=$p(c),l=((t,e)=>t.flatMap(t=>{const[n,s]=t.padCenters,o="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,i="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2,r={minX:n.x-o,maxX:n.x+o,minY:n.y-i,maxY:n.y+i},a={minX:s.x-o,maxX:s.x+o,minY:s.y-i,maxY:s.y+i},c=o/2,h=i/2,l="horizontal"===e.orientation?{minX:Math.min(n.x,s.x),maxX:Math.max(n.x,s.x),minY:t.center.y-h,maxY:t.center.y+h}:{minX:t.center.x-c,maxX:t.center.x+c,minY:Math.min(n.y,s.y),maxY:Math.max(n.y,s.y)};return[{regionId:`${t.jumperId}_pad1`,ports:[],d:{bounds:r,center:n,polygon:Yp(r),isPad:!0,isThroughJumper:!1}},{regionId:`${t.jumperId}_bridge`,ports:[],d:{bounds:l,center:t.center,polygon:Yp(l),isPad:!1,isThroughJumper:!0}},{regionId:`${t.jumperId}_pad2`,ports:[],d:{bounds:a,center:s,polygon:Yp(a),isPad:!0,isThroughJumper:!1}}]}))(n.jumpers,{orientation:e.orientation,padWidth:e.padWidth,padHeight:e.padHeight}),d=((t,e,n=1e-5)=>{const s=[];let o=0;for(let i=0;i<t.length;i++){const r=t[i];if(r?.d.polygon)for(let a=i+1;a<t.length;a++){const i=t[a];if(!i?.d.polygon)continue;const c=Wp(r,i,n);for(const t of c){const n=Bp(t),a=Math.floor(n/e),c=Math.max(1,a-1);for(let e=0;e<c;e++){const n=jp(t,(e+1)/(c+1));s.push({portId:"tp_"+o++,region1:r,region2:i,d:{x:n.x,y:n.y}})}}}}return s})(h,e.portSpacing),u=((t,e,n=1e-5)=>{const s=[];let o=0,i=0;const r=t.filter(t=>t.d.isPad),a=t.filter(t=>t.d.isThroughJumper&&!t.d.isPad);for(const t of r)for(const i of e){const e=Wp(t,i,n),r=Hp(e,n);for(const e of r){const n=jp(e,.5);s.push({portId:"jp_"+o++,region1:t,region2:i,d:{x:n.x,y:n.y}})}}for(const t of a)for(const e of r){const o=Zp(t.d.bounds,e.d.bounds,n);if(!o)continue;const r=Fp(o);s.push({portId:"jip_"+i++,region1:e,region2:t,d:{x:r.x,y:r.y}})}return s})(l,h),p=[...d,...u];return(t=>{for(const e of t)e.region1.ports.push(e),e.region2.ports.push(e)})(p),{regions:[...h,...l],ports:p,jumperLocations:n.jumpers.map((t,e)=>({center:t.center,orientation:t.orientation,padRegions:[l[3*e],l[3*e+2]].filter(t=>Boolean(t))})),topLayerRegions:h,jumperRegions:l,jumpers:n.jumpers,vias:n.vias,bounds:n.bounds}},Jp=class extends Ln{getSolverName(){return"JumperPrepatternSolver2_HyperGraph"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;hyperParameters;jumperGraphSolver=null;xyConnections=[];graphBounds=null;jumperLocations=[];solvedRoutes=[];jumpers=[];phase="jumperGraph";curvySolvers=[];currentCurvySolverIndex=0;routeInfos=[];regionCurvedPaths=new Map;constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.hyperParameters=t.hyperParameters??{},this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=this._buildColorMap())}getConstructorParams(){return this.constructorParams}_buildColorMap(){const t=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],e={},n=new Set;for(const t of this.nodeWithPortPoints.portPoints)n.add(t.connectionName);let s=0;for(const o of Array.from(n))e[o]=t[s%t.length],s++;return e}_normalizeRegionPolygonsToBounds(t){for(const e of t.regions){const t=e.d,n=t?.polygon,s=t?.bounds;if(!n||0===n.length||!s)continue;let o=1/0,i=1/0;for(const t of n)o=Math.min(o,t.x),i=Math.min(i,t.y);const r=s.minX-o,a=s.minY-i;(Math.abs(r)>1e-12||Math.abs(a)>1e-12)&&(t.polygon=n.map(t=>({x:t.x+r,y:t.y+a}))),t.polygonPerimeterCache&&(t.polygonPerimeterCache=void 0)}return t}_getPatternConfig(){return{cols:this.hyperParameters.COLS??1,rows:this.hyperParameters.ROWS??1}}_generate0603Grid(t,e,n,s){const o="horizontal"===e?t.rows:t.cols,i="horizontal"===e?t.cols:t.rows,r=s.maxX-s.minX,a=s.maxY-s.minY,c=.35,h=this.hyperParameters.TRACE_CHANNELS_BETWEEN_JUMPERS??1,l=this.traceWidth*h+2*this.obstacleMargin,d="horizontal"===e?2.15:1,u="horizontal"===e?1:2.15,p="horizontal"===e?"x":"y",f="staggered"===n,m=f&&"x"===p?d/2:f?u/2:0,g=Math.max(0,r-1),x=Math.max(0,a-1),v=Math.max(0,g-(f&&"x"===p?m:0)),b=Math.max(0,x-(f&&"y"===p?m:0)),P=o>1?Math.max(d+l,(v-d)/(o-1)):d,S=i>1?Math.max(u+l,(b-u)/(i-1)):u,M=qp({cols:o,rows:i,orientation:e,pattern:n,staggerAxis:p,colSpacing:P,rowSpacing:S,padWidth:.9,padHeight:1,padGap:c,clearance:l,boundsPadding:0,maxNeckRatio:.4,minSplitBalanceRatio:.2}),N=M.bounds,I=(N.minX+N.maxX)/2,_=(N.minY+N.maxY)/2,C=y((s.minX+s.maxX)/2-I,(s.minY+s.maxY)/2-_);return this._normalizeRegionPolygonsToBounds(To(M,C))}_initializeGraph(){const t=this.nodeWithPortPoints,e=this._getPatternConfig(),n=this.hyperParameters.ORIENTATION??"vertical",s=this.hyperParameters.JUMPER_TYPE??"1206x4",o=this.hyperParameters.PATTERN??"grid",i={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};let r;if(this.graphBounds=i,"0603"===s){const t=this._generate0603Grid(e,n,o,i);if(!t)return this.error=`0603 grid (${e.cols}x${e.rows}) is too large to fit in node bounds`,this.failed=!0,!1;r=t}else r=ri({cols:e.cols,rows:e.rows,marginX:Math.max(1.2,.3*e.cols),marginY:Math.max(1.2,.3*e.rows),outerPaddingX:.4,outerPaddingY:.4,parallelTracesUnderJumperCount:2,innerColChannelPointCount:3,innerRowChannelPointCount:3,outerChannelXPointCount:3,outerChannelYPointCount:3,regionsBetweenPads:!0,orientation:n,bounds:i});if(r.regions.length>0){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(const s of r.regions){if(!s.d?.isPad)continue;const i=s.d?.bounds;i&&(t=Math.min(t,i.minX),e=Math.max(e,i.maxX),n=Math.min(n,i.minY),o=Math.max(o,i.maxY))}const a="0603"===s?.5:1;if(t-a<i.minX||e+a>i.maxX||n-a<i.minY||o+a>i.maxY)return this.error=`baseGraph bounds (${t.toFixed(2)}, ${n.toFixed(2)}, ${e.toFixed(2)}, ${o.toFixed(2)}) exceed node bounds (${i.minX.toFixed(2)}, ${i.minY.toFixed(2)}, ${i.maxX.toFixed(2)}, ${i.maxY.toFixed(2)})`,this.failed=!0,!1}this.jumperLocations=r.jumperLocations?.map(t=>({center:t.center,orientation:t.orientation,padRegions:t.padRegions}))??[];const a=new Map;for(const e of t.portPoints){const t=a.get(e.connectionName);t?t.points.push(e):a.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.xyConnections=[];for(const[t,e]of Array.from(a.entries()))e.points.length<2||this.xyConnections.push({start:{x:e.points[0].x,y:e.points[0].y},end:{x:e.points[1].x,y:e.points[1].y},connectionId:t});if(0===this.xyConnections.length)return this.solved=!0,!0;const c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[],i=_o(t.regions);for(const r of e){const{start:e,end:a,connectionId:c}=r,h=Ko(`conn:${c}:start`,e.x,e.y);n.push(h);const l=Ko(`conn:${c}:end`,a.x,a.y);n.push(l);const d=oi(e.x,e.y,t.regions,i);if(d){const t=Jo(`conn:${c}:start-port`,h,d.region,d.portPosition);s.push(t)}const u=oi(a.x,a.y,t.regions,i);if(u){const t=Jo(`conn:${c}:end-port`,l,u.region,u.portPosition);s.push(t)}const p={connectionId:c,mutuallyConnectedNetworkId:c,startRegion:h,endRegion:l};o.push(p)}return{regions:n,ports:s,connections:o}})(r,this.xyConnections);return this.jumperGraphSolver=new qo({inputGraph:{regions:c.regions,ports:c.ports},inputConnections:c.connections}),this.jumperGraphSolver.MAX_ITERATIONS*=3,!0}_step(){switch(this.phase){case"jumperGraph":this._stepJumperGraph();break;case"curvyTrace":this._stepCurvyTrace();break;case"done":this.solved=!0}}_stepJumperGraph(){if(!this.jumperGraphSolver){if(this._initializeGraph(),this.solved)return;if(!this.jumperGraphSolver)return void(this.failed=!0)}this.activeSubSolver=this.jumperGraphSolver,this.jumperGraphSolver.step(),this.jumperGraphSolver.solved?(this._initializeCurvyTraceSolvers(),this.curvySolvers.length>0?this.phase="curvyTrace":(this._finalizeCurvyTraceResults(),this.phase="done",this.solved=!0)):this.jumperGraphSolver.failed&&(this.error=this.jumperGraphSolver.error,this.failed=!0)}_stepCurvyTrace(){if(this.currentCurvySolverIndex>=this.curvySolvers.length)return this._finalizeCurvyTraceResults(),this.phase="done",void(this.solved=!0);const t=this.curvySolvers[this.currentCurvySolverIndex],e=t.solver;if(this.activeSubSolver=e,e.step(),e.solved){const n=t.regionId;this.regionCurvedPaths.has(n)||this.regionCurvedPaths.set(n,new Map);for(const t of e.outputTraces){const e=t.networkId??"",s=t.points.map(t=>({x:t.x,y:t.y})),o={path:s,start:s[0]??{x:0,y:0},end:s[s.length-1]??{x:0,y:0}};this.regionCurvedPaths.get(n).has(e)||this.regionCurvedPaths.get(n).set(e,[]),this.regionCurvedPaths.get(n).get(e).push(o)}this.currentCurvySolverIndex++}else e.failed&&this.currentCurvySolverIndex++}_initializeCurvyTraceSolvers(){if(!this.jumperGraphSolver)return;const t=new Set,e=[];for(const t of this.jumperLocations)for(const n of t.padRegions){const t=n.d.bounds,s=n.d.center;e.push({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:s.x,y:s.y},networkIds:[]})}const n=new Map;for(let e=0;e<this.jumperGraphSolver.solvedRoutes.length;e++){const s=this.jumperGraphSolver.solvedRoutes[e],o=s.connection.connectionId,i=this.nodeWithPortPoints.portPoints.find(t=>t.connectionName===o)?.rootConnectionName,r=[],a=[];let c=null,h=null;for(let l=0;l<s.path.length;l++){const d=s.path[l],u=d.port,p=d.lastRegion,f=u.region1,m=u.region2;let g;if(p)f&&f.regionId!==p.regionId?g=f:m&&m.regionId!==p.regionId&&(g=m);else{const t=s.path[l+1],e=t?.lastRegion;if(e&&(f&&f.regionId===e.regionId?g=f:m&&m.regionId===e.regionId&&(g=m)),!g){const t=t=>t?.regionId?.startsWith("conn:");g=!f||t(f)||f.d?.isPad||f.d?.isThroughJumper?!m||t(m)||m.d?.isPad||m.d?.isThroughJumper?!f||f.d?.isPad||f.d?.isThroughJumper?(!m||m.d?.isPad||m.d?.isThroughJumper)&&f||m:f:m:f}}if(g&&(!c||g.regionId!==c.regionId)){if(c&&h){a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:u});const t=c.regionId;n.has(t)||n.set(t,[]),n.get(t).push({regionId:c.regionId,region:c,routeIndex:e,connectionName:o,rootConnectionName:i,entryPort:h,exitPort:u})}c=g,h=u}if(p?.d?.isThroughJumper&&!t.has(p.regionId)){t.add(p.regionId);const e=p.d.bounds,n=p.d.center,s=e.maxX-e.minX>e.maxY-e.minY,o="0603"===(this.hyperParameters.JUMPER_TYPE??"1206x4")?"0603":"1206x4_pair";s?r.push({route_type:"jumper",start:{x:e.minX,y:n.y},end:{x:e.maxX,y:n.y},footprint:o}):r.push({route_type:"jumper",start:{x:n.x,y:e.minY},end:{x:n.x,y:e.maxY},footprint:o})}}if(c&&h){const t=s.path[s.path.length-1];a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:t?.port||null})}this.routeInfos.push({connectionId:o,rootConnectionName:i,jumpers:r,traversals:a})}for(let t=0;t<this.routeInfos.length;t++){const n=this.routeInfos[t],s=n.rootConnectionName??n.connectionId;for(const t of n.jumpers){const n=[t.start,t.end];for(const t of n)for(const n of e){const e=Math.abs(n.center.x-t.x),o=Math.abs(n.center.y-t.y);e<.1&&o<.1&&(n.networkIds.includes(s)||n.networkIds.push(s))}}}for(const[t,s]of n){if(0===s.length)continue;const n=s[0].region;if(n.d.isPad||n.d.isThroughJumper)continue;const o=n.d.bounds,i=[];for(const t of s)i.push({start:{x:t.entryPort.d.x,y:t.entryPort.d.y},end:{x:t.exitPort.d.x,y:t.exitPort.d.y},networkId:t.rootConnectionName??t.connectionName});const r=.01,a=e.filter(t=>t.minX<=o.maxX+r&&t.maxX>=o.minX-r&&t.minY<=o.maxY+r&&t.maxY>=o.minY-r).map(t=>{const e=s.map(t=>t.rootConnectionName??t.connectionName),n=t.networkIds.find(t=>e.includes(t));return{minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:t.center,networkId:n}}),c={bounds:o,waypointPairs:i,obstacles:a,preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth},h=new Tu(c);this.curvySolvers.push({solver:h,regionId:t,traversals:s.map(t=>({routeIndex:t.routeIndex,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName}))})}}_finalizeCurvyTraceResults(){const t=(t,e)=>Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2);for(let e=0;e<this.routeInfos.length;e++){const n=this.routeInfos[e],s=[];for(const e of n.traversals){const o=e.regionId,i=n.rootConnectionName??n.connectionId,r=this.regionCurvedPaths.get(o)?.get(i);let a=null;if(r&&r.length>0){const n={x:e.entryPort.d.x,y:e.entryPort.d.y},s=e.exitPort?{x:e.exitPort.d.x,y:e.exitPort.d.y}:null;let o=null,i=1/0;for(const e of r){const r=t(e.start,n)+(s?t(e.end,s):0);r<i&&(i=r,o=e)}o&&i<.5&&(a=o.path)}if(a&&a.length>0){for(let t=s.length>0?1:0;t<a.length;t++)s.push({x:a[t].x,y:a[t].y,z:0})}else 0===s.length&&s.push({x:e.entryPort.d.x,y:e.entryPort.d.y,z:0}),e.exitPort&&s.push({x:e.exitPort.d.x,y:e.exitPort.d.y,z:0})}this.solvedRoutes.push({connectionName:n.connectionId,rootConnectionName:n.rootConnectionName,traceThickness:this.traceWidth,route:s,jumpers:n.jumpers})}}getOutput(){return this.solvedRoutes}getOutputJumpers(){if(this.jumpers.length>0)return this.jumpers;const t=new Map;for(const e of this.solvedRoutes)for(const n of e.jumpers){const s=[n.start,n.end];for(const n of s){const s=`${n.x.toFixed(3)},${n.y.toFixed(3)}`,o=t.get(s)??[];e.rootConnectionName&&!o.includes(e.rootConnectionName)&&o.push(e.rootConnectionName),o.includes(e.connectionName)||o.push(e.connectionName),t.set(s,o)}}const e=this.hyperParameters.JUMPER_TYPE??"1206x4",n=wn["0603"===e?"0603":"1206x4_pair"];for(const s of this.jumperLocations){const o="horizontal"===s.orientation,i=s.padRegions.map(e=>{const n=e.d.bounds,s=e.d.center,o=n.maxX-n.minX,i=n.maxY-n.minY,r=`${s.x.toFixed(3)},${s.y.toFixed(3)}`;return{type:"rect",center:s,width:o,height:i,layers:["top"],connectedTo:[...t.get(r)??[]]}}),r={jumper_footprint:e,center:s.center,orientation:s.orientation,width:o?n.length:n.width,height:o?n.width:n.length,pads:i};this.jumpers.push(r)}return this.jumpers=this.jumpers.filter(t=>t.pads.some(t=>t.connectedTo.length>0)),this.jumpers}visualize(){if(this.jumperGraphSolver&&!this.solved)return this.jumperGraphSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints,n={minX:e.center.x-e.width/2,maxX:e.center.x+e.width/2,minY:e.center.y-e.height/2,maxY:e.center.y+e.height/2};t.lines.push({points:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY},{x:n.minX,y:n.minY}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"});for(const n of e.portPoints)t.points.push({x:n.x,y:n.y,label:n.connectionName,color:this.colorMap[n.connectionName]??"blue"});for(const e of this.solvedRoutes){const n=this.colorMap[e.connectionName]??"blue";for(let s=0;s<e.route.length-1;s++){const o=e.route[s],i=e.route[s+1];t.lines.push({points:[o,i],strokeColor:In(n,.2),strokeWidth:e.traceThickness,layer:"route-layer-0"})}for(const s of e.jumpers)this._drawJumperPads(t,s,In(n,.5))}return t}_drawJumperPads(t,e,n){const s=wn[e.footprint],o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)>Math.abs(i),a=r?s.padLength:s.padWidth,c=r?s.padWidth:s.padLength;t.rects.push({center:{x:e.start.x,y:e.start.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*s.padWidth,layer:"jumper-body"})}},Kp=class extends is{constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;connMap;baseHyperParameters;availableJumperTypes;solvedRoutes=[];jumpers=[];constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.connMap=t.connMap,this.baseHyperParameters=t.hyperParameters??{},this.availableJumperTypes=t.availableJumperTypes??["0603"],this.MAX_ITERATIONS=1e6,this.GREEDY_MULTIPLIER=1,this.MIN_SUBSTEPS=1e3}getConstructorParams(){return this.constructorParams}getHyperParameterDefs(){const t=[],e=this.nodeWithPortPoints,n=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1);t.push({name:"0603_max_rows_and_cols_vert_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:n.cols,ROWS:n.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const s=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1,"staggered");t.push({name:"0603_max_rows_and_cols_vert_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:s.cols,ROWS:s.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const o=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2);t.push({name:"0603_max_rows_and_cols_vert_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:o.cols,ROWS:o.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const i=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2,"staggered");t.push({name:"0603_max_rows_and_cols_vert_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:i.cols,ROWS:i.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const r=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1);t.push({name:"0603_max_rows_and_cols_horz_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:r.cols,ROWS:r.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const a=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1,"staggered");t.push({name:"0603_max_rows_and_cols_horz_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:a.cols,ROWS:a.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const c=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2);t.push({name:"0603_max_rows_and_cols_horz_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:c.cols,ROWS:c.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const h=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2,"staggered");t.push({name:"0603_max_rows_and_cols_horz_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:h.cols,ROWS:h.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]}),t.push({name:"1206x4",possibleValues:[{JUMPER_TYPE:"1206x4"}]});return t.push({name:"1206x4_cols",possibleValues:[1,2,3,4,6,8,10].map(t=>({COLS:t}))}),t.push({name:"1206x4_rows",possibleValues:[1,2,3,4,8].map(t=>({ROWS:t}))}),t.push({name:"orientation",possibleValues:[{ORIENTATION:"vertical"},{ORIENTATION:"horizontal"}]}),t}isValidCombination(t){const{JUMPER_TYPE:e,COLS:n,ROWS:s}=t,o=[1,2,4,6,8],i=[1,2,3,4,6,8,10],r=[1,2,3,4,8];return"0603"===e?o.includes(n)&&o.includes(s):"1206x4"===e&&(i.includes(n)&&r.includes(s))}getCombinationDefs(){return[["0603_max_rows_and_cols_vert_1trace_grid"],["0603_max_rows_and_cols_vert_1trace_staggered"],["0603_max_rows_and_cols_horz_1trace_grid"],["0603_max_rows_and_cols_horz_1trace_staggered"],["0603_max_rows_and_cols_vert_2trace_grid"],["0603_max_rows_and_cols_vert_2trace_staggered"],["0603_max_rows_and_cols_horz_2trace_grid"],["0603_max_rows_and_cols_horz_2trace_staggered"],["1206x4","1206x4_cols","1206x4_rows","orientation"]]}calculateMax0603ConfigWithTraceChannels(t,e,n,s,o="grid"){const i=this.traceWidth*s+2*this.obstacleMargin,r="horizontal"===n?2.15:1,a="horizontal"===n?1:2.15,c="horizontal"===n?"x":"y",h="staggered"===o&&"x"===c?r/2:"staggered"===o?a/2:0,l=Math.max(0,t-1),d=Math.max(0,e-1),u=Math.max(0,l-("staggered"===o&&"x"===c?h:0)),p=Math.max(0,d-("staggered"===o&&"y"===c?h:0)),f=r+i,m=a+i,g=Math.max(1,Math.floor(1+(u-r)/f)),y=Math.max(1,Math.floor(1+(p-a)/m));return"vertical"===n?{cols:g,rows:y}:{cols:y,rows:g}}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs();this.supervisedSolvers=[];for(const n of e){const e=n.some(t=>t.startsWith("0603_max_rows_and_cols_")),s=n.includes("1206x4");if(e&&!this.availableJumperTypes.includes("0603"))continue;if(s&&!this.availableJumperTypes.includes("1206x4"))continue;const o=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of o){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){return new Jp({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,hyperParameters:{COLS:t.COLS,ROWS:t.ROWS,ORIENTATION:t.ORIENTATION,JUMPER_TYPE:t.JUMPER_TYPE,PATTERN:t.PATTERN,TRACE_CHANNELS_BETWEEN_JUMPERS:t.TRACE_CHANNELS_BETWEEN_JUMPERS},obstacleMargin:this.obstacleMargin})}computeG(t){const e=t.hyperParameters.COLS*t.hyperParameters.ROWS;return t.iterations/1e4+.25*e}computeH(t){return 1-(t.progress||0)}onSolve(t){this.solvedRoutes=t.solver.solvedRoutes,this.jumpers=t.solver.getOutputJumpers()}getOutput(){return this.solvedRoutes}getOutputJumpers(){return this.jumpers}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function Qp(t){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:0,route:t.route,vias:[],jumpers:t.jumpers}}var tf=class extends Ln{getSolverName(){return"JumperHighDensitySolver"}allNodes;nodeAnalyses;routes;colorMap;traceWidth;obstacleMargin;viaDiameter;connMap;hyperParameters;availableJumperTypes;capacityMeshNodes;capacityMeshEdges;capacityMeshNodeMap;nodeAdjacencyMap;nodesWithoutCrossings;nodesWithCrossings;curvyIntraNodeSolvers;currentCurvySolverIndex;jumperSolvers;currentJumperSolverIndex;phase;jumpers=[];constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.15,obstacleMargin:s=.15,viaDiameter:o=.3,connMap:i,hyperParameters:r,capacityMeshNodes:a=[],capacityMeshEdges:c=[],availableJumperTypes:h}){super(),this.allNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.obstacleMargin=s,this.viaDiameter=o,this.connMap=i,this.hyperParameters=r,this.capacityMeshNodes=a,this.capacityMeshEdges=c,this.availableJumperTypes=h??["0603"],this.capacityMeshNodeMap=new Map(a.map(t=>[t.capacityMeshNodeId,t])),this.nodeAdjacencyMap=this._buildNodeAdjacencyMap(),this.nodesWithoutCrossings=[],this.nodesWithCrossings=[],this.nodeAnalyses=[],this.curvyIntraNodeSolvers=[],this.currentCurvySolverIndex=0,this.jumperSolvers=[],this.currentJumperSolverIndex=0,this.phase="analyzing",this._analyzeNodes();const l=1e3*this.nodesWithoutCrossings.length,d=1e5*this.nodesWithCrossings.length;this.MAX_ITERATIONS=l+d+100}_buildNodeAdjacencyMap(){const t=new Map;for(const e of this.capacityMeshEdges){const[n,s]=e.nodeIds;t.has(n)||t.set(n,new Set),t.has(s)||t.set(s,new Set),t.get(n).add(s),t.get(s).add(n)}return t}_analyzeNodes(){for(const t of this.allNodes){const e=xh(t),n={node:t,hasCrossings:e.numSameLayerCrossings>0,numSameLayerCrossings:e.numSameLayerCrossings};this.nodeAnalyses.push(n),e.numSameLayerCrossings>0?this.nodesWithCrossings.push(t):this.nodesWithoutCrossings.push(t)}this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done"}_step(){switch(this.phase){case"analyzing":this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done";break;case"curvy":this._stepCurvySolvers();break;case"jumpers":this._stepJumperSolvers();break;case"done":this.solved=!0}}_getAdjacentObstacles(t){const e=[],n=this.nodeAdjacencyMap.get(t.capacityMeshNodeId);if(!n||0===n.size)return e;const s=new Map(this.allNodes.map(t=>[t.capacityMeshNodeId,t]));for(const t of n){const n=this.capacityMeshNodeMap.get(t);if(!n)continue;if(!n._containsObstacle&&!n._containsTarget)continue;const o=n.center.x-n.width/2,i=n.center.y-n.height/2,r=n.center.x+n.width/2,a=n.center.y+n.height/2;let c;if(n._containsTarget)if(n._targetConnectionName)c=n._targetConnectionName;else{const e=s.get(t);e&&e.portPoints.length>0&&(c=e.portPoints[0].rootConnectionName??e.portPoints[0].connectionName)}e.push({minX:o,minY:i,maxX:r,maxY:a,networkId:c})}return e}_initializeCurvySolvers(){for(const t of this.nodesWithoutCrossings){const e=this._getAdjacentObstacles(t),n=new Eu({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:e});this.curvyIntraNodeSolvers.push(n)}}_stepCurvySolvers(){if(0===this.curvyIntraNodeSolvers.length)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());const t=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];if(this.activeSubSolver=t,!t)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());if(t.step(),t.solved){this.routes.push(...t.routes),this.currentCurvySolverIndex++;for(let t=this.currentCurvySolverIndex;t<this.curvyIntraNodeSolvers.length;t++){this.curvyIntraNodeSolvers[t];const e=this.nodesWithoutCrossings[t],n=this._getAdjacentObstacles(e),s=new Eu({nodeWithPortPoints:e,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:n});this.curvyIntraNodeSolvers[t]=s}this.currentCurvySolverIndex>=this.curvyIntraNodeSolvers.length&&(this.phase=this.nodesWithCrossings.length>0?"jumpers":"done","jumpers"===this.phase&&this._initializeJumperSolvers())}else t.failed&&(this.error=`CurvyIntraNodeSolver failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}_initializeJumperSolvers(){for(const t of this.nodesWithCrossings){const e=new Kp({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,connMap:this.connMap,availableJumperTypes:this.availableJumperTypes});this.jumperSolvers.push(e)}}_stepJumperSolvers(){if(0===this.jumperSolvers.length)return this.phase="done",void(this.solved=!0);const t=this.jumperSolvers[this.currentJumperSolverIndex];if(this.activeSubSolver=t,!t)return this.phase="done",void(this.solved=!0);if(t.step(),t.solved){for(const e of t.solvedRoutes)this.routes.push(Qp(e));this.jumpers.push(...t.getOutputJumpers()),this.currentJumperSolverIndex++,this.currentJumperSolverIndex>=this.jumperSolvers.length&&(this.phase="done",this.solved=!0)}else t.failed&&(this.error=`HyperJumperPrepatternSolver2 failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}computeProgress(){const t=this.allNodes.length;if(0===t)return 1;let e=0;e+=this.currentCurvySolverIndex;const n=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];n&&(e+=n.progress),e+=this.currentJumperSolverIndex;const s=this.jumperSolvers[this.currentJumperSolverIndex];return s&&(e+=s.progress),e/t}getConstructorParams(){return{nodePortPoints:this.allNodes,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,viaDiameter:this.viaDiameter,connMap:this.connMap,hyperParameters:this.hyperParameters,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,availableJumperTypes:this.availableJumperTypes}}getOutputJumpers(){return this.jumpers}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.failed&&this.activeSubSolver)return this.activeSubSolver.visualize();if("curvy"===this.phase&&this.curvyIntraNodeSolvers[this.currentCurvySolverIndex])return this.curvyIntraNodeSolvers[this.currentCurvySolverIndex].visualize();if("jumpers"===this.phase&&this.jumperSolvers[this.currentJumperSolverIndex])return this.jumperSolvers[this.currentJumperSolverIndex].visualize();for(const e of this.routes){const n=e.rootConnectionName??e.connectionName,s=Wn(e.route,e.connectionName,this.colorMap[n]);for(const n of s)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:In(n.color??"gray",.75),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?"10, 5":void 0});for(const s of e.vias)t.circles.push({center:s,radius:e.viaDiameter/2,fill:In(this.colorMap[n]??"gray",.5),layer:"via"});if("jumpers"in e&&e.jumpers)for(const s of e.jumpers){const e=this.colorMap[n]??"gray",o=s.footprint??"1206",i=wn[o],r=s.end.x-s.start.x,a=s.end.y-s.start.y,c=Math.abs(r)>Math.abs(a),h=c?i.padLength:i.padWidth,l=c?i.padWidth:i.padLength;t.rects.push({center:s.start,width:h,height:l,fill:In(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:s.end,width:h,height:l,fill:In(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[s.start,s.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*i.padWidth,layer:"jumper-body"})}}for(const e of this.nodeAnalyses){const n=e.node;n.center.x,n.width,n.center.x,n.width,n.center.y,n.height,n.center.y,n.height;t.rects.push({center:n.center,width:n.width,height:n.height,fill:e.hasCrossings?"rgba(255, 200, 0, 0.1)":"rgba(0, 200, 0, 0.1)",stroke:e.hasCrossings?"rgba(255, 150, 0, 0.5)":"rgba(0, 150, 0, 0.5)",label:[n.capacityMeshNodeId,e.hasCrossings?`crossings: ${e.numSameLayerCrossings}`:"no crossings"].join("\n")})}return t}};function ef(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var nf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline3"}netToPointPairsSolver;traceKeepoutSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[ef("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),ef("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),ef("relateNodesToOffBoardConnections",Xd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),ef("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),ef("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),ef("portPointPathingSolver",zh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:10*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!0,NODE_PF_FACTOR:100,MAX_RIPS:100*t.effort,RIPPING_ENABLED:!0,MAX_RIPPING_PF_THRESHOLD:.9,MIN_RIPPING_PF_THRESHOLD:.1,RANDOM_RIP_FRACTION:.05,NODE_PF_MAX_PENALTY:1e3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Vd({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),ef("highDensitySolver",tf,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,connMap:t.connMap,capacityMeshNodes:t.capacityNodes??[],capacityMeshEdges:t.capacityEdges??[],availableJumperTypes:t.srj.availableJumperTypes}]),ef("highDensityStitchSolver",qd,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,connectionPathResults:t.multiSectionPortPointOptimizer?.connectionResults??t.portPointPathingSolver?.connectionsWithResults??[],colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),ef("traceKeepoutSolver",Yd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??t.highDensityStitchSolver?.mergedHdRoutes??[],obstacles:t.srj.obstacles,jumpers:t.highDensitySolver?.getOutputJumpers()??[],connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.traceKeepoutSolver?.visualize(),a=this.deadEndSolver?.visualize(),c=this.availableSegmentPointSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.portPointPathingSolver?.visualize(),d=this.multiSectionPortPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensitySolver?.visualize(),f=this.simpleHighDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.traceSimplificationSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,a,c,h,l,d,u?jn(b,u):null,p?jn(b,p):null,f?jn(b,f):null,m,g,r,y,this.solved?jn(b,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`;s.obstacleId=o;const i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputJumpers(){return this.highDensitySolver?this.highDensitySolver.getOutputJumpers():[]}getOutputSimpleRouteJson(){const t=this.getOutputJumpers();return{...this.srj,traces:this.getOutputSimplifiedPcbTraces(),jumpers:t.length>0?t:void 0}}},sf=t=>{const{candidates:e,mapOfCapacityMeshNodeIdToRef:n}=t;let s=!0;for(const t of e){let e=!1;t.port.nodeIds.forEach(t=>{const s=n.get(t);if(!s)throw new Error(`Could not find capacity mesh node for id ${t}`);s._containsObstacle&&(e=!0)}),e||(s=!1)}return s},of=t=>t.depth+1e3*t.countOfCrampedPortPointsInPath,rf=class extends N{constructor(t){if(super(),this.input=t,this.input.depthLimit<1)throw new Error("Depth limit must be at least 1");this._setup()}queue=[];resultExploredPortPoints=[];currentExploredPortPoints=null;visitedExploredPortPoints=[];getSolverName(){return"singleTargetNecessaryCrampedPortPointSolver"}_setup(){const t=this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(this.input.target.capacityMeshNodeId)??[];for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:1,parent:null,countOfCrampedPortPointsInPath:e.cramped?1:0};this.queue.push(t)}this.visitedExploredPortPoints=[...new Set(this.queue.map(t=>t.port))]}_step(){if(0===this.queue.length)return this.currentExploredPortPoints=null,void(this.solved=!0);for(;this.queue.length>0;){if(this.currentExploredPortPoints=this.queue.shift(),this.currentExploredPortPoints.depth===this.input.depthLimit){this.resultExploredPortPoints.push(this.currentExploredPortPoints);continue}const t=this.currentExploredPortPoints.port.nodeIds.map(t=>{const e=this.input.mapOfCapacityMeshNodeIdToRef.get(t);if(!e)throw new Error(`Could not find capacity mesh node for id ${t}`);return e}).flatMap(t=>this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(t.capacityMeshNodeId)??[]);for(const e of t)this.input.shouldIgnoreCrampedPortPoints&&e.cramped||this.queue.push({port:e,depth:this.currentExploredPortPoints.depth+1,parent:this.currentExploredPortPoints,countOfCrampedPortPointsInPath:this.currentExploredPortPoints.countOfCrampedPortPointsInPath+(e.cramped?1:0)})}this.visitedExploredPortPoints=[...new Set(this.queue.map(t=>t.port)),...this.visitedExploredPortPoints],this.solved=!0}getOutput(){return this.resultExploredPortPoints}visualize(){const t={points:[],rects:[]};for(const e of this.visitedExploredPortPoints)t.points.push({...e,color:e.cramped?"blue":"green"});return t}},af=class extends N{constructor(t){super(),this.input=t,this._setup()}unprocessedTargets=[];targetNode=[];currentTarget;crampedPortPointsToKeep=new Set;candidatesAtDepth=[];isRunningCrampedPass=!1;activeSubSolver=null;nodeMap=new Map;mapOfCapacityMeshNodeIdToSegmentPortPoints=new Map;getSolverName(){return"multiTargetNecessaryCrampedPortPointSolver"}_setup(){this.targetNode=this.input.capacityMeshNodes.filter(t=>t._containsObstacle);const t=this.input.simpleRouteJson.connections.flatMap(t=>t.pointsToConnect);this.targetNode=this.targetNode.filter(e=>{let n=!1;return t.forEach(t=>{B(t,e)<=0&&(n=!0)}),n}),this.unprocessedTargets=[...this.targetNode],this.unprocessedTargets.sort((t,e)=>t.center.x-e.center.x);for(const t of this.input.capacityMeshNodes)this.nodeMap.set(t.capacityMeshNodeId,t);for(const t of this.input.sharedEdgeSegments)for(const e of t.portPoints){const t=e.nodeIds;for(const n of t){if(!this.nodeMap.get(n))throw new Error(`Could not find capacity mesh node for id ${n}`);const t=this.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(n)||[];this.mapOfCapacityMeshNodeIdToSegmentPortPoints.set(n,[...t,e])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver._step(),!this.activeSubSolver.solved)return;if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error);if(this.candidatesAtDepth=this.activeSubSolver.getOutput(),this.activeSubSolver=null,!this.currentTarget)return this.failed=!0,void(this.error="Missing current capacity mesh node while finishing BFS");if(!this.isRunningCrampedPass){return sf({candidates:this.candidatesAtDepth,mapOfCapacityMeshNodeIdToRef:this.nodeMap})||0===this.candidatesAtDepth.length?(this.isRunningCrampedPass=!0,void(this.activeSubSolver=new rf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!1,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.currentTarget=void 0)}let t=this.candidatesAtDepth.filter(t=>{const e=t.port;return e.nodeIds.map(t=>{const e=this.nodeMap.get(t);if(!e)throw this.failed=!0,this.error=`Could not find capacity mesh node for id ${t}`,new Error(`Could not find capacity mesh node for id ${t}`);return e}).every(t=>!t._containsObstacle)&&e.cramped});sf({candidates:t,mapOfCapacityMeshNodeIdToRef:this.nodeMap})&&(this.error=`All candidates are blocked by obstacles even after including cramped port points for capacity mesh node ${this.currentTarget.capacityMeshNodeId}`),this.candidatesAtDepth=[...t].sort((t,e)=>of(t)-of(e));const e=this.candidatesAtDepth[0];return e&&0!==t.length?this.crampedPortPointsToKeep.add(e.port):this.error=`No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`,this.isRunningCrampedPass=!1,void(this.currentTarget=void 0)}if(!this.currentTarget)return this.currentTarget=this.unprocessedTargets.shift(),this.currentTarget?(this.isRunningCrampedPass=!1,this.candidatesAtDepth=[],void(this.activeSubSolver=new rf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!0,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.solved=!0)}getOutput(){return this.input.sharedEdgeSegments.map(t=>({...t,portPoints:t.portPoints.filter(t=>!t.cramped||this.crampedPortPointsToKeep.has(t))}))}visualize(){const t={rects:[],points:[]};for(const e of this.targetNode)t.rects.push({...e,fill:this.currentTarget?.capacityMeshNodeId===e.capacityMeshNodeId?"rgba(255, 0, 0, 0.5)":"rgba(255, 0, 0, 0.2)"});for(const e of this.candidatesAtDepth)t.points.push({...e.port,color:e.port.cramped?"blue":"green"});for(const e of this.crampedPortPointsToKeep)t.points.push({...e,color:"blue"});return this.activeSubSolver?M(t,this.activeSubSolver.visualize()):t}};function cf(t,e){if(null==t)throw new Error(e)}function hf(t){if(0===B(t.point,t.region.d)){if(function(t,e){const n=[];for(const s of t)e.includes(s)&&n.push(s);return n}(("layers"in t.point?t.point.layers:[t.point.layer]).map(e=>Rn(e,t.layerCount)),t.region.d.availableZ).length>0)return!0}return!1}function lf(t,e){const n={lines:[],points:[]};if(!t)return n;let s=t.shift();if(!s)return n;const o=[];n.points.push({...s.port.d,color:"rgb(255, 50, 50)",label:`g: ${s.g}\nh: ${s.h}\nf: ${s.f}\nripRequired: ${s.ripRequired}`});do{o.push({x:s.port.d.x,y:s.port.d.y,z:s.port.d.z}),s=s.parent}while(s);o.reverse();const i=o[0]?.z??0;o.unshift({x:e.x,y:e.y,z:i});for(let t=0;t<o.length-1;t++){const e=o[t],s=o[t+1];let i;i=e.z===s.z?0===e.z?void 0:"10 5":"3 3 10",n.lines.push({points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"rgba(255, 250, 50, 1)",strokeWidth:.1,strokeDash:i})}for(const e of t)n.points.push({...e.port.d,color:"rgb(0, 64, 255)",label:`${e.port.portId}\ng: ${e.g}\nh: ${e.h}\nf: ${e.f}\nripRequired: ${e.ripRequired}`});return n}function df(t,e){const n={lines:[],points:[]};for(const s of t){const t=e[s.connection.connectionId]??"rgba(255, 50, 50, 1)",o=[{x:s.connection.startRegion.d.center.x,y:s.connection.startRegion.d.center.y,z:s.connection.startRegion.d.availableZ[0]??0}];for(const t of s.path)o.push({x:t.port.d.x,y:t.port.d.y,z:t.port.d.z});o.push({x:s.connection.endRegion.d.center.x,y:s.connection.endRegion.d.center.y,z:s.connection.endRegion.d.availableZ[0]??0});for(let e=0;e<o.length-1;e++){const s=o[e],i=o[e+1];let r;r=s.z===i.z?0===s.z?void 0:"10 5":"3 3 10";const a={points:[{x:s.x,y:s.y},{x:i.x,y:i.y}],strokeColor:t,strokeWidth:.1,strokeDash:r};n.lines.push(a)}}return n}function uf(t,e){const n={lines:[],points:[]};for(const s of t){const t=s.startRegion.d.center,o=s.endRegion.d.center,i=(t.x+o.x)/2,r=(t.y+o.y)/2,a=e[s.connectionId]??"rgba(255, 50, 150, 0.8)";n.points.push({x:i,y:r,color:a,label:s.connectionId}),n.lines.push({points:[t,o],strokeColor:a,strokeWidth:.05,strokeDash:0===(s.startRegion.d.availableZ[0]??0)?void 0:"10 5"})}return n}function pf(t){const e={rects:[],points:[]};for(const n of t.regions)e.rects.push({center:n.d.center,width:n.d.width,height:n.d.height,fill:"rgba(200, 200, 200, 0.5)",label:n.regionId});for(const n of t.ports)e.points.push({x:n.d.x,y:n.d.y,color:"rgba(4, 90, 20, 0.3)",label:n.portId});return e}var ff=class extends yo{constructor(t){super({inputConnections:t.connections,inputGraph:t.graph,greedyMultiplier:t.weights.GREEDY_MULTIPLIER,ripCost:t.weights.RIPPING_PF_COST,rippingEnabled:t.flags.RIPPING_ENABLED}),this.params=t,this.regionMemoryPfMap=t.opts?.regionMemoryPfMap??new Map,this.baseRegionFailureCostMap=new Map,this.regionRipCountMap=new Map,this.totalRipCount=0,t.weights.MAX_ITERATIONS_PER_PATH>0&&(this.MAX_ITERATIONS=t.weights.MAX_ITERATIONS_PER_PATH*t.effort)}regionMemoryPfMap;baseRegionFailureCostMap;regionRipCountMap;totalRipCount;estimateCostToEnd(t){const e=this.currentEndRegion;return cf(e,"Current end region is undefined"),k(t.d,e.d.center)}computeH(t){const e=t,n=this.computeDistanceTraveled(e);if(this.params.weights.RANDOM_WALK_DISTANCE>0&&n<this.params.weights.RANDOM_WALK_DISTANCE)return 0;const s=this.estimateCostToEnd(t.port),o=(t.port.d.distToCentermostPortOnZ-this.params.weights.CENTER_OFFSET_FOCUS_SHIFT)*this.params.weights.CENTER_OFFSET_DIST_PENALTY_FACTOR,i=t.nextRegion?.regionId??t.lastRegion?.regionId,r=i?this.regionMemoryPfMap.get(i)??0:0;return s+o+this.computeMemoryPfPenalty(r)+this.computeDeviation(t)*this.params.weights.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){const s=this.currentConnection;cf(s,"Current connection is undefined");const o=this.getBaseRegionFailureCost(t),i=this.computeRegionPfWithAdditionalSegment(t,e,n,s.connectionId,s.mutuallyConnectedNetworkId);if(i>=this.NODE_MAX_PF)return this.params.weights.NODE_PF_MAX_PENALTY;const r=this.pfToFailureCost(i),a=Math.max(0,r-o);return Math.min(this.params.weights.NODE_PF_MAX_PENALTY,a*this.params.weights.NODE_PF_FACTOR)}computeG(t){const e=t,n=super.computeG(t);return e.nextRegion!==this.currentEndRegion?n:n+this.computeEndRegionCloseCost(e)}getPortUsagePenalty(t){const e=t.assignment;if(!e)return 0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n?0:.5*Math.max(1,this.params.weights.NODE_PF_FACTOR)+this.params.weights.BASE_CANDIDATE_COST}getRipsRequiredForPortUsage(t,e,n){const s=t.assignments??[];if(0===s.length)return[];return s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection?.mutuallyConnectedNetworkId&&(t.regionPort1!==e&&t.regionPort2!==e&&(t.regionPort1!==n&&t.regionPort2!==n&&L(t.regionPort1.d,t.regionPort2.d,e.d,n.d))))}selectCandidatesForEnteringRegion(t){const e=this.currentConnection?.startRegion,n=this.currentConnection?.endRegion;cf(e,"Current connection or start region is undefined"),cf(n,"Current connection or end region is undefined");const s=t.filter(t=>{const s=t.nextRegion;return!s?.d._containsObstacle||(s===e||s===n)});let o=this.params.flags.FORCE_CENTER_FIRST?this.getCenterFirstEnteringRegionCandidates(s):s;const i=-this.params.weights.MIN_ALLOWED_BOARD_SCORE;if(i>0){const t=o.filter(t=>t.g+t.h<=i);t.length>0&&(o=t)}return o}routeSolvedHook(t){this.baseRegionFailureCostMap.clear();const e=new Set;for(const n of t.path){const t=n.lastRegion;t&&e.add(t)}for(const t of e){const e=this.computeRegionPfFromAssignments(t);this.regionMemoryPfMap.set(t.regionId,e)}if(!t.requiredRip)return;if(this.unprocessedConnections.length<2)return;const[n,...s]=this.unprocessedConnections;this.unprocessedConnections=[...s,n]}computeRoutesToRip(t){const e=super.computePortOverlapRoutes(t),n=new Set(e),s=new Map;t.path.map(t=>{if(!t.lastPort||!t.lastRegion)return;const e=this.getRipsRequiredForPortUsage(t.lastRegion,t.lastPort,t.port);if(0===e.length)return null;const n=s.get(t.lastRegion)??new Set;for(const t of e)n.add(t.solvedRoute);s.set(t.lastRegion,n)});const o=t.path.flatMap(t=>t.lastRegion?[t.lastRegion]:[]),i=Array.from(new Set([...s.keys(),...o])),r=this.params.weights.SHUFFLE_SEED+this.iterations+this.solvedRoutes.length+this.totalRipCount,a=Gn(i,r);for(const e of a){if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;const s=this.getRegionRippingPfThreshold(e.regionId);let o=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n});if(this.regionMemoryPfMap.set(e.regionId,o),o<=s)continue;const i=new Set;let a=0;for(;o>s&&!(this.totalRipCount>=this.params.weights.MAX_RIPS);){if(!e.assignments||0===e.assignments.length)throw new Error("We are trying to rip a region with no assignments, this should not happen");const s=e.assignments.map(e=>{const s=e.solvedRoute;return e.connection.connectionId===t.connection.connectionId?null:n.has(s)?void 0:s}).filter(t=>!!t);if(0===s.length)break;const c=Gn(s,r+a+i.size)[0];if(!c)break;i.add(c.connection),n.add(c),this.totalRipCount++,a++,this.regionRipCountMap.set(e.regionId,(this.regionRipCountMap.get(e.regionId)??0)+1),o=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n}),this.regionMemoryPfMap.set(e.regionId,o)}}if(n.size>e.size){if(this.totalRipCount>=this.params.weights.MAX_RIPS)return n;const e=this.solvedRoutes.filter(e=>!n.has(e)&&e.connection.connectionId!==t.connection.connectionId);if(0===e.length)return n;const s=Math.max(1,Math.floor(this.params.weights.RANDOM_RIP_FRACTION*e.length)),o=Gn(e,r);let i=0;for(const t of o){if(i>=s)break;if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;n.has(t)||(n.add(t),i++,this.totalRipCount++)}}return n}computeDeviation(t){const e=this.currentConnection?.startRegion.d.center,n=this.currentConnection?.endRegion.d.center;cf(e,"Current connection or start region is undefined"),cf(n,"Current connection or end region is undefined");return X(t.port.d,e,n)}computeDistanceTraveled(t){let e=0,n=t;for(;n?.parent;)e+=k(n.parent.port.d,n.port.d),n=n.parent;return e}computeMemoryPfPenalty(t){const e=Math.min(Math.max(t,0),.999999),n=Math.min(this.params.weights.NODE_PF_MAX_PENALTY,-Math.log(1-e));return n*this.params.weights.MEMORY_PF_FACTOR+n*this.params.weights.NODE_PF_FACTOR*.01}computeEndRegionCloseCost(t){const e=this.currentConnection,n=this.currentEndRegion;cf(e,"Current connection is undefined"),cf(n,"Current end region is undefined");const s=e.endRegion.d.center,o={portId:`end-target:${e.connectionId}`,region1:n,region2:n,d:{portId:`end-target:${e.connectionId}`,x:s.x,y:s.y,z:t.port.d.z,distToCentermostPortOnZ:0,regions:[n,n]}};return this.computeIncreasedRegionCostIfPortsAreUsed(n,t.port,o)}getCenterFirstEnteringRegionCandidates(t){const e=new Map;for(const n of t){const t=n.port.d.z,s=e.get(t)??[];s.push(n),e.set(t,s)}const n=[];for(const t of e.values()){const e=t.sort((t,e)=>t.port.d.distToCentermostPortOnZ-e.port.d.distToCentermostPortOnZ)[0];if(!e)continue;if(this.isPortAvailableForCurrentNet(e.port)){n.push(e);continue}const s=t.sort((t,e)=>t.port.d.x!==e.port.d.x?t.port.d.x-e.port.d.x:t.port.d.y-e.port.d.y),o=[];let i=[];for(const t of s)this.isPortAvailableForCurrentNet(t.port)?i.push(t):i.length>0&&(o.push(i),i=[]);i.length>0&&o.push(i);for(const t of o)n.push(t[Math.floor(t.length/2)])}return n}isPortAvailableForCurrentNet(t){const e=t.assignment;if(!e)return!0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n}computeRegionPfFromAssignments(t){const e=this.getRegionAssignedPortPoints(t),n={...t.d,portPoints:e},s=xh(n),o=t.d;return Ph(o,s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}clampPf(t){return Math.min(Math.max(t,0),.999999)}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.params.weights.NODE_PF_MAX_PENALTY))}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.params.weights.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseRegionFailureCost(t){const e=this.baseRegionFailureCostMap.get(t.regionId);if(null!=e)return e;const n=this.computeRegionPfFromAssignments(t),s=this.pfToFailureCost(n);return this.baseRegionFailureCostMap.set(t.regionId,s),s}getRegionAssignedPortPoints(t){return(t.assignments??[]).flatMap(t=>{const e=t.regionPort1.d,n=t.regionPort2.d,s=t.connection.connectionId,o=t.connection.mutuallyConnectedNetworkId;return[{x:e.x,y:e.y,z:e.z,connectionName:s,rootConnectionName:o},{x:n.x,y:n.y,z:n.z,connectionName:s,rootConnectionName:o}]})}computeRegionPfWithAdditionalSegment(t,e,n,s,o){const i=this.getRegionAssignedPortPoints(t),r=[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:s,rootConnectionName:o},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:s,rootConnectionName:o}],a={...t.d,portPoints:[...i,...r]},c=xh(a);return Ph(t.d,c.numSameLayerCrossings,c.numEntryExitLayerChanges,c.numTransitionPairCrossings)}getRegionRippingPfThreshold(t){const e=this.regionRipCountMap.get(t)??0,n=Math.max(1,Math.floor(this.params.weights.MAX_RIPS/10)),s=Math.min(1,e/n);return(this.params.weights.START_RIPPING_PF_THRESHOLD||this.params.weights.RIPPING_PF_THRESHOLD||.3)*(1-s)+(this.params.weights.END_RIPPING_PF_THRESHOLD||1)*s}computeRegionPf({region:t,newlySolvedRoute:e,routesToRip:n}){const s=[...(t.assignments??[]).filter(t=>!n.has(t.solvedRoute)).flatMap(t=>{const e=t.regionPort1,n=t.regionPort2,s=t.connection.connectionId,o=t.connection.mutuallyConnectedNetworkId;return[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:s,rootConnectionName:o},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:s,rootConnectionName:o}]}),...e.path.flatMap(n=>{if(!n.lastPort||n.lastRegion!==t)return[];const s=n.lastPort,o=n.port;return[{x:s.d.x,y:s.d.y,z:s.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId},{x:o.d.x,y:o.d.y,z:o.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId}]})],o={capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:s,availableZ:t.d.availableZ},i=xh(o),r=t.d;return Ph(r,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings)}getOutput(){new Map(this.params.graph.regions.map(t=>[t.regionId,t]));const t=new Set;for(const e of this.params.connections)t.add(e.startRegion.regionId),t.add(e.endRegion.regionId);const e=new Map;for(const t of this.solvedRoutes){const n=t.path;if(0===n.length)continue;const s=n[0]?.port,o=n[n.length-1]?.port;if(!s||!o)continue;const i=t.connection.connectionId,r=t.connection.mutuallyConnectedNetworkId,a=t.connection.startRegion.regionId,c=t.connection.endRegion.regionId,h=e.get(a)??[];h.push({portPointId:s.d.portId,x:s.d.x,y:s.d.y,z:s.d.z,connectionName:i,rootConnectionName:r}),e.set(a,h);const l=e.get(c)??[];l.push({portPointId:o.d.portId,x:o.d.x,y:o.d.y,z:o.d.z,connectionName:i,rootConnectionName:r}),e.set(c,l)}const n=[],s=[];for(const o of this.params.graph.regions){const i=(o.assignments??[]).flatMap(t=>{const e=t.connection.connectionId,n=t.connection.mutuallyConnectedNetworkId;return[{portPointId:t.regionPort1.d.portId,x:t.regionPort1.d.x,y:t.regionPort1.d.y,z:t.regionPort1.d.z,connectionName:e,rootConnectionName:n},{portPointId:t.regionPort2.d.portId,x:t.regionPort2.d.x,y:t.regionPort2.d.y,z:t.regionPort2.d.z,connectionName:e,rootConnectionName:n}]}),r=[];if(o.d._containsObstacle&&t.has(o.regionId)){const t=e.get(o.regionId)??[],n=[];for(const e of t){i.some(t=>t.connectionName===e.connectionName&&t.rootConnectionName===e.rootConnectionName&&t.portPointId===e.portPointId)||n.push(e)}i.push(...n);const s=new Map;for(const t of i){const e=`${t.connectionName}::${t.rootConnectionName??""}`,n=s.get(e)??[];n.push(t),s.set(e,n)}for(const[t,e]of s.entries()){const[n,s=""]=t.split("::"),i=e[0];i&&r.push({portPointId:`center:${o.regionId}:${n}:${s}`,x:o.d.center.x,y:o.d.center.y,z:i.z,connectionName:n,rootConnectionName:s||void 0})}}const a=[...i,...r];a.length>0&&n.push({capacityMeshNodeId:o.d.capacityMeshNodeId,center:o.d.center,width:o.d.width,height:o.d.height,portPoints:a,availableZ:o.d.availableZ});const c=o.ports.map(t=>{const e=t.d.regions.some(t=>Boolean(t.d._offBoardConnectionId));return{portPointId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,connectionNodeIds:t.d.regions.map(t=>t.regionId),distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,connectsToOffBoardNode:e}});s.push({capacityMeshNodeId:o.d.capacityMeshNodeId,center:o.d.center,width:o.d.width,height:o.d.height,portPoints:c,availableZ:o.d.availableZ,_containsObstacle:o.d._containsObstacle,_containsTarget:o.d._containsTarget,_offBoardConnectionId:o.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:o.d._offBoardConnectedCapacityMeshNodeIds})}return{nodesWithPortPoints:n,inputNodeWithPortPoints:s}}visualize(){return function(t){let e={};return e=t.reduce((t,e)=>t&&e?M(t,e):{},e),e||{}}([pf(this.params.graph),uf(this.params.connections,this.params.colorMap??{}),lf(this.candidateQueue.peekMany(100),this.currentConnection?.startRegion.d.center),df(this.solvedRoutes,this.params.colorMap??{})])}};function mf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var gf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[mf("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),mf("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),mf("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),mf("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),mf("necessaryCrampedPortPointSolver",af,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),mf("portPointPathingSolver",ff,t=>{const{graph:e,connections:n}=function(t){const e={ports:[],regions:[]},n=[];for(const n of t.capacityMeshNodes)e.regions.push({regionId:n.capacityMeshNodeId,d:n,ports:[]});for(const n of t.segmentPortPoints){const[t,s]=n.nodeIds,o=e.regions.find(e=>e.regionId===t),i=e.regions.find(t=>t.regionId===s);cf(o,`Could not find region with id ${t} for segment port point ${n.segmentPortPointId}`),cf(i,`Could not find region with id ${s} for segment port point ${n.segmentPortPointId}`);for(const t of n.availableZ){const s={portId:`${n.segmentPortPointId}::${t}`,x:n.x,y:n.y,z:t,distToCentermostPortOnZ:0,regions:[o,i]},r={portId:n.segmentPortPointId,d:s,region1:o,region2:i};e.ports.push(r),o.ports.push(r),i.ports.push(r)}}for(const s of t.simpleRouteJsonConnections){const[o,i]=s.pointsToConnect,r=e.regions.find(e=>hf({point:o,region:e,layerCount:t.layerCount})),a=e.regions.find(e=>hf({point:i,region:e,layerCount:t.layerCount}));cf(r,`Could not find start region for connection "${s.name}"`),cf(a,`Could not find end region for connection "${s.name}"`),n.push({connectionId:s.name,mutuallyConnectedNetworkId:s.rootConnectionName??s.name,startRegion:r,endRegion:a,simpleRouteConnection:s})}return{graph:e,connections:n}}({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,segmentPortPoints:t.availableSegmentPointSolver.getOutput().flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:e,connections:n,layerCount:t.srj.layerCount,effort:t.effort,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:.05,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:.5,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,RIPPING_PF_THRESHOLD:.3,START_RIPPING_PF_THRESHOLD:.3,END_RIPPING_PF_THRESHOLD:1,MAX_RIPS:1e3,RANDOM_RIP_FRACTION:.3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4,GREEDY_MULTIPLIER:.7,MIN_ALLOWED_BOARD_SCORE:-1e4}}]}),mf("uniformPortDistributionSolver",ze,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),mf("highDensityRouteSolver",uh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),mf("highDensityStitchSolver",Qh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),mf("traceSimplificationSolver",_l,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),mf("traceWidthSolver",Cl,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.necessaryCrampedPortPointSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,f,c,h,l,d?jn(y,d):null,u,p,this.solved?jn(y,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},yf=class extends Yl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=>this.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length&&(t.width>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length>0)&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=>this.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=>t===n)&&t.push(e)}e.set(n,t)}const n=new Set;for(const t of e.values())for(const e of t)n.add(e);this.finishedNodes=this.finishedNodes.filter(t=>!n.has(t));for(const n of t){const t=e.get(n)||[],s=n.layers&&n.layers.length>0?Array.from(new Set(n.layers.map(t=>Rn(t,this.srj.layerCount)))).sort((t,e)=>t-e):Array.from({length:this.srj.layerCount},(t,e)=>this.srj.layerCount-e-1);let o=n.center.x-n.width/2,i=n.center.x+n.width/2,r=n.center.y-n.height/2,a=n.center.y+n.height/2;for(const e of t){const t=e.center.x-e.width/2,n=e.center.x+e.width/2,s=e.center.y-e.height/2,c=e.center.y+e.height/2;o=Math.min(o,t),i=Math.max(i,n),r=Math.min(r,s),a=Math.max(a,c)}const c=i-o,h=a-r,l=(o+i)/2,d=(r+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x>=o&&e.x<=i&&e.y>=r&&e.y<=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===s.length?`z${s[0]}`:`z${s.join(",")}`,availableZ:s,_depth:0,_containsTarget:u,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=n,this.finishedNodes.push(p)}}_step(){const t=this.unfinishedNodes.pop();if(!t)return this.insertAssignableObstaclesAsNodes(),void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e;if(e)s.push(t);else{if(o){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget&&this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?s.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)&&!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},xf=.005,vf=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver_OnlyMergeTargets"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n._assignedViaObstacle?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):n._containsTarget?n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]):(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId));e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new $n(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<xf&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<xf&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<xf&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<xf&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Layer Node Merger (Only Merge Targets)"};for(const e of this.newNodes)t.rects.push(kl(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=kl(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=kl(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},bf=class extends Ln{getSolverName(){return"AssignableViaNodeMergerSolver"}newNodes;obstacleToNodesMap;obstaclesToProcess;mergedNodeIds;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.newNodes=[],this.obstacleToNodesMap=new Map,this.mergedNodeIds=new Set;for(const e of t){const t=e._assignedViaObstacle;if(t){const n=this.obstacleToNodesMap.get(t)||[];n.push(e),this.obstacleToNodesMap.set(t,n)}else this.newNodes.push(e)}this.obstaclesToProcess=Array.from(this.obstacleToNodesMap.keys())}_step(){const t=this.obstaclesToProcess.pop();if(!t)return void(this.solved=!0);const e=this.obstacleToNodesMap.get(t);if(!e||0===e.length)return;let n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;const r=new Set;let a=!1;for(const t of e){const e=t.center.x-t.width/2,c=t.center.x+t.width/2,h=t.center.y-t.height/2,l=t.center.y+t.height/2;n=Math.min(n,e),s=Math.max(s,c),o=Math.min(o,h),i=Math.max(i,l);for(const e of t.availableZ)r.add(e);t._containsTarget&&(a=!0)}const c=s-n,h=i-o,l=(n+s)/2,d=(o+i)/2,u=Array.from(r).sort((t,e)=>t-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===u.length?`z${u[0]}`:`z${u.join(",")}`,availableZ:u,_containsTarget:a,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=t;for(const t of e)this.mergedNodeIds.add(t.capacityMeshNodeId);this.newNodes.push(p)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Assignable Via Node Merger"};for(const e of this.newNodes){const n=kl(e);e._assignedViaObstacle&&(n.stroke="rgba(255, 0, 255, 0.8)",n.label=`${n.label||""}\n(merged via)`),t.rects.push(n)}const e=this.obstaclesToProcess[this.obstaclesToProcess.length-1];if(e){const n=this.obstacleToNodesMap.get(e)||[];for(const e of n){const n=kl(e,{rectMargin:.01});n.stroke="rgba(0, 255, 0, 0.8)",n.label=`${n.label||""}\n(to be merged)`,t.rects.push(n)}}return t}},Pf=class extends Ln{constructor(t){const{simpleRouteJson:e,nodes:n,edges:s,colorMap:o,MAX_ITERATIONS:i=1e6,hyperParameters:r={}}=t;super(),this.inputParams=t,this.hyperParameters=r,this.MAX_ITERATIONS=i,this.simpleRouteJson=e,this.nodes=n,this.edges=s,this.colorMap=o??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges);const a=this.nodes.filter(t=>t._containsTarget);this.unprocessedConnectionPairs=Gn(this.simpleRouteJson.connections.map(t=>{const[e,n]=t.pointsToConnect;return{start:a.find(t=>k(t.center,e)<t.width/2),end:a.find(t=>k(t.center,n)<t.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=>t.availableZ.length>1)}getSolverName(){return"AssignableViaCapacityPathingSolver_DirectiveSubOptimal"}GREEDY_MULTIPLIER=1.5;simpleRouteJson;nodes;edges;colorMap;MAX_ITERATIONS;hyperParameters;usedNodeMap=new Map;nodeMap;nodeEdgeMap;unprocessedConnectionPairs;solvedRoutes=[];activeConnectionPair=null;ogUnprocessedSubpaths=null;unprocessedSubpaths=null;solvedSubpaths=null;activeSubpath=null;viaNodes=[];closestViaForConnectionStartMap=new Map;closestViaForConnectionEndMap=new Map;getConstructorParams(){return this.inputParams}lastStepOperation="none";computeClosestViaForAllConnections(){this.closestViaForConnectionStartMap.clear(),this.closestViaForConnectionEndMap.clear();for(const t of this.unprocessedConnectionPairs){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length>0){const n=e.reduce((e,n)=>{const s=this._dist(e,t.start);return this._dist(n,t.start)<s?n:e});this.closestViaForConnectionStartMap.set(t,n);const s=e.reduce((e,n)=>{const s=this._dist(e,t.end);return this._dist(n,t.end)<s?n:e});this.closestViaForConnectionEndMap.set(t,s)}}}_step(){if(!this.activeConnectionPair)return this.activeConnectionPair=this.unprocessedConnectionPairs.shift(),this.activeConnectionPair?(this.computeClosestViaForAllConnections(),void(this.lastStepOperation="dequeueConnectionPair")):void(this.solved=!0);if(this.activeConnectionPair&&!this.unprocessedSubpaths)return this.unprocessedSubpaths=this.breakConnectionPairIntoSubpaths(this.activeConnectionPair),this.ogUnprocessedSubpaths=this.unprocessedSubpaths.slice(),this.solvedSubpaths=[],void(this.lastStepOperation="breakConnectionPairIntoSubpaths");if(this.activeSubpath){if(this.activeSubpath&&(this.stepSolveSubpath(this.activeSubpath),this.activeSubpath.solved))return this.solvedSubpaths.push(this.activeSubpath),this.activeSubpath=null,this.clearCandidateNodes(),void(this.lastStepOperation="finishedSolvingSubpath");this.lastStepOperation="stepSolveSubpath"}else{if(this.activeSubpath=this.unprocessedSubpaths.shift(),!this.activeSubpath){const t=this.activeConnectionPair;return this.activeConnectionPair=null,this.unprocessedSubpaths=null,this.ogUnprocessedSubpaths=null,this.activeSubpath=null,this.solvedRoutes.push(this.createSolvedRoute(this.solvedSubpaths,t)),void(this.lastStepOperation="finishedSolvingConnectionPair")}this.lastStepOperation="dequeueSubpath"}}queuedCandidateNodes=[];visitedNodes=new Set;_dist(t,e){return Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)}stepSolveSubpath(t){const{start:e,end:n}=t;if(e.capacityMeshNodeId===n.capacityMeshNodeId)return t.path=[e],t.solved=!0,void this.usedNodeMap.set(e.capacityMeshNodeId,!0);if(0===this.queuedCandidateNodes.length&&0===this.visitedNodes.size){const t=this._dist(e,n),s={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(s)}let s;for(this.queuedCandidateNodes.sort((t,e)=>t.f-e.f);this.queuedCandidateNodes.length&&!s;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(s=t)}if(!s)return this.failed=!0,void(this.error="No viable candidates left");if(this.visitedNodes.add(s.node.capacityMeshNodeId),s.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=s;for(;n;)e.unshift(n.node),this.usedNodeMap.set(n.node.capacityMeshNodeId,!0),n=n.prevCandidate;return t.path=e,void(t.solved=!0)}const o=this.getNeighbors(s.node);for(const t of o){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+this.GREEDY_MULTIPLIER*i,a=this.queuedCandidateNodes.findIndex(t=>t.node.capacityMeshNodeId===e);if(a>=0){if(this.queuedCandidateNodes[a].g<=o)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:s,node:t,g:o,h:i,f:r})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const s of n){const[n,o]=s.nodeIds,i=n===t.capacityMeshNodeId?o:n,r=this.nodeMap.get(i);r&&e.add(r)}const s=this.activeSubpath?.layer;return Array.from(e).filter(t=>!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle&&(!t._containsTarget&&(!this.usedNodeMap.has(t.capacityMeshNodeId)&&!(void 0!==s&&!t.availableZ.includes(s)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const s=this._dist(t.node,e);return t.g+s}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e<t.length;e++){const s=t[e];s.path?0===e?n.push(...s.path):n.push(...s.path.slice(1)):(0===e&&n.push(s.start),e===t.length-1&&n.push(s.end))}return{connection:e.connection,path:n}}breakConnectionPairIntoSubpaths(t){var e,n;if(!(e=[this.hyperParameters.DIRECTIVE_SEED??0,this.solvedRoutes.length],n=this.hyperParameters.FORCE_VIA_TRAVEL_CHANCE??0,Un(e.reduce((t,e)=>t+16807*e%2147483647,0))()<n))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const s=this.getClosestVia(t.start),o=this.getFarVia(s,t.end),i=t.start.availableZ[0]??0,r=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:s,solved:!1,layer:i}),i===r?(a.push({start:s,end:o,solved:!1,layer:0===i?1:0}),a.push({start:o,end:t.end,solved:!1,layer:r})):a.push({start:s,end:t.end,solved:!1,layer:r}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=>!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=>this._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=>this._dist(e,t)-this._dist(n,t));const s=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(s>0&&n.length>1){const t=Un((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(s+1));return n[Math.min(e,n.length-1)]}return n[0]}getFarVia(t,e){if(0===this.viaNodes.length)return t;const n=null!=this.hyperParameters.FAR_VIA_MIN_DISTANCE?this.hyperParameters.FAR_VIA_MIN_DISTANCE:50,s=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);const o=this.viaNodes.filter(e=>!this.usedNodeMap.has(e.capacityMeshNodeId)&&e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!s.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n);if(0===o.length){const s=this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n).sort((t,n)=>this._dist(t,e)-this._dist(n,e));if(s.length>0)return s[0];return this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=>this._dist(t,e)-this._dist(n,e))[0]??t}o.sort((t,n)=>this._dist(t,e)-this._dist(n,e));const i=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(i>0&&o.length>1){const t=Un((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(i+1));return o[Math.min(e,o.length-1)]}return o[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n&&n.length>0&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=>!!t&&"number"==typeof t.x&&"number"==typeof t.y&&!Number.isNaN(t.x)&&!Number.isNaN(t.y)&&Number.isFinite(t.x)&&Number.isFinite(t.y),n=t=>"number"==typeof t&&!Number.isNaN(t)&&Number.isFinite(t);for(const s of this.nodes){const o=this.queuedCandidateNodes.some(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId),i=this.queuedCandidateNodes.find(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId);if(e(s.center)&&n(s.width)&&n(s.height)){const e=kl(s,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:o?"rgba(255, 128, 255, 0.5)":s._containsTarget?"rgba(0, 150, 255, 0.15)":s._containsObstacle?"rgba(255, 0, 0, 0.1)":"rgba(200, 200, 200, 0.05)",label:[`ID: ${s.capacityMeshNodeId}`,`Size: ${s.width.toFixed(2)}x${s.height.toFixed(2)}`,`Z: ${s.availableZ.join(", ")}`,i?`g: ${i.g.toFixed(2)}`:"",i?`h: ${i.h.toFixed(2)}`:"",i?`f: ${i.f.toFixed(2)}`:"",s._containsTarget?"TARGET":"",s._containsObstacle?"OBSTACLE":""].filter(t=>t).join("\n")})}}for(const n of this.edges){const[s,o]=n.nodeIds,i=this.nodeMap.get(s),r=this.nodeMap.get(o);i?.center&&r?.center&&e(i.center)&&e(r.center)&&t.lines.push({points:[i.center,r.center],strokeColor:"rgba(150, 150, 150, 0.2)"})}for(let n=0;n<this.solvedRoutes.length;n++){const s=this.solvedRoutes[n],o=s.path,i="blue";for(let s=0;s<o.length-1;s++){const r=o[s],a=o[s+1];if(r?.center&&a?.center&&e(r.center)&&e(a.center)){const e=r.availableZ.includes(1)&&a.availableZ.includes(1),s=n%5*.02;t.lines.push({points:[{x:r.center.x+s,y:r.center.y+s},{x:a.center.x+s,y:a.center.y+s}],strokeColor:i,strokeDash:e?"5 5":void 0})}}if(o.length>0){const n=o[0],i=o[o.length-1];n?.center&&e(n.center)&&t.points.push({x:n.center.x,y:n.center.y,label:`START: ${s.connection.name}`}),i?.center&&e(i.center)&&t.points.push({x:i.center.x,y:i.center.y,label:`END: ${s.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n<this.solvedSubpaths.length;n++){const s=this.solvedSubpaths[n];if(s.path&&s.path.length>1)for(let n=0;n<s.path.length-1;n++){const o=s.path[n],i=s.path[n+1];o?.center&&i?.center&&e(o.center)&&e(i.center)&&t.lines.push({points:[o.center,i.center],strokeColor:"green",strokeDash:1===s.layer?"3 3":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,s=this.activeSubpath.end?.center;n&&s&&e(n)&&e(s)&&(t.lines.push({points:[n,s],strokeColor:"orange",strokeDash:"5 5"}),t.points.push({x:n.x,y:n.y,label:"ACTIVE START"}),t.points.push({x:s.x,y:s.y,label:"ACTIVE END"}))}const s=this.queuedCandidateNodes.slice(0,10).sort((t,e)=>t.f-e.f);for(let n=0;n<s.length;n++){const o=.6*(1-n/10),i=[];let r=s[n];for(;r;)i.push(r.node),r=r.prevCandidate;if(i.reverse(),i.length>1){const n=i.map(t=>t.center).filter(t=>e(t));n.length>1&&t.lines.push({points:n,strokeColor:In("purple",1-o),strokeDash:1===this.activeSubpath?.layer?"4 2":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,s=this.activeConnectionPair.end?.center;n&&s&&e(n)&&e(s)&&t.lines.push({points:[n,s],strokeColor:"cyan",strokeDash:"20 5"})}if(this.ogUnprocessedSubpaths&&3===this.ogUnprocessedSubpaths.length){const[,s]=this.ogUnprocessedSubpaths;if(s.start?.center&&e(s.start.center)){const e=Math.max(s.start.width||0,s.start.height||0);n(e)&&e>0&&(t.circles.push({center:s.start.center,radius:e,stroke:"blue"}),t.points.push({x:s.start.center.x,y:s.start.center.y,label:"DIRECTIVE VIA 1"}))}if(s.end?.center&&e(s.end.center)){const e=Math.max(s.end.width||0,s.end.height||0);n(e)&&e>0&&(t.circles.push({center:s.end.center,radius:e,stroke:"purple"}),t.points.push({x:s.end.center.x,y:s.end.center.y,label:"DIRECTIVE VIA 2"}))}}if(this.queuedCandidateNodes.length>0)for(const n of this.queuedCandidateNodes){const s=n.node;s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.05,fill:"rgba(255, 255, 0, 0.6)",stroke:"yellow"})}if(this.visitedNodes.size>0)for(const n of this.visitedNodes){const s=this.nodeMap.get(n);s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.08,fill:"rgba(128, 128, 128, 0.5)",stroke:"gray"})}return t}},Sf=class extends is{getSolverName(){return"HyperAssignableViaCapacityPathingSolver"}constructorParams;constructor(t){super(),this.constructorParams=t,this.MAX_ITERATIONS=t.MAX_ITERATIONS??12e4,this.MIN_SUBSTEPS=5,this.GREEDY_MULTIPLIER=1.35}getHyperParameterDefs(){return[{name:"traceOrderingSeed",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5},{SHUFFLE_SEED:6},{SHUFFLE_SEED:7},{SHUFFLE_SEED:8},{SHUFFLE_SEED:9}]},{name:"forceViaTravelChance",possibleValues:[{FORCE_VIA_TRAVEL_CHANCE:.6},{FORCE_VIA_TRAVEL_CHANCE:.8},{FORCE_VIA_TRAVEL_CHANCE:.9}]}]}computeG(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length,s=e>0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-s)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e>0?1-n/e:0}generateSolver(t){return new Pf({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function Mf(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function Nf(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var If=class extends Ln{getSolverName(){return"OffboardCapacityNodeSolver"}capacityNodes;capacityEdges;enhancedEdges=[];animationState="showing_nodes";assignableNodes=[];shownNodes=[];pendingEdges=[];createdEdges=[];nextEdgeId=0;nodeMap=new Map;constructor(t){super(),this.capacityNodes=t.capacityNodes,this.capacityEdges=t.capacityEdges,this.nodeMap=Mf(this.capacityNodes),this.enhancedEdges=[...this.capacityEdges],this.initializeAssignableNodes(),this.initializePendingEdges(),this.MAX_ITERATIONS=this.assignableNodes.length+this.pendingEdges.length+10}initializeAssignableNodes(){for(const t of this.capacityNodes){const e=t._assignedViaObstacle;e?.offBoardConnectsTo&&e.offBoardConnectsTo.length>0&&this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const s of n.offBoardConnectsTo)t.has(s)||t.set(s,[]),t.get(s).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length>1)for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++)this.pendingEdges.push({node1:n[t],node2:n[s],netName:e})}_step(){switch(this.animationState){case"showing_nodes":if(this.assignableNodes.length>0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState="showing_edges";break;case"showing_edges":if(this.pendingEdges.length>0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),s=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(s),this.createdEdges.push(s)}else this.animationState="done",this.solved=!0;break;case"done":this.solved=!0}}createOffboardEdge(t,e,n){return{capacityMeshEdgeId:"offboard_"+this.nextEdgeId++,nodeIds:[t.capacityMeshNodeId,e.capacityMeshNodeId],isOffboardEdge:!0,offboardNetName:n}}visualize(){const t=[],e=[],n=[],s=new Set(this.shownNodes.map(t=>t.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(s.has(e.nodeIds[0])||s.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"rgba(0, 200, 0, 0.5)",strokeWidth:.05})}}for(let t=0;t<this.shownNodes.length;t++){const s=this.shownNodes[t],o=s._assignedViaObstacle,i=t===this.shownNodes.length-1&&"showing_nodes"===this.animationState;n.push({center:s.center,width:s.width,height:s.height,fill:i?"rgba(255, 165, 0, 0.5)":"rgba(173, 216, 230, 0.5)",stroke:i?"orange":"blue",strokeWidth:i?.15:.1}),e.push({x:s.center.x,y:s.center.y,color:i?"orange":"blue",label:`${i?"NEW: ":""}${s.capacityMeshNodeId}\n${o?.offBoardConnectsTo?.join(", ")||""}`})}for(let n=0;n<this.createdEdges.length;n++){const s=this.createdEdges[n],o=n===this.createdEdges.length-1&&"showing_edges"===this.animationState,i=this.nodeMap.get(s.nodeIds[0]),r=this.nodeMap.get(s.nodeIds[1]);if(i&&r){t.push({points:[i.center,r.center],strokeColor:o?"red":"orange",strokeWidth:o?.2:.1,strokeDasharray:"0.3,0.15"});const n=Nf(i.center,r.center);e.push({x:n.x,y:n.y,color:o?"red":"orange",label:`${o?"NEW: ":""}⚡ ${s.offboardNetName}`})}}let o="Offboard Capacity Node Solver";switch(this.animationState){case"showing_nodes":o+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case"showing_edges":o+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case"done":o+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:o}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=>t.isOffboardEdge)}};function _f(t,e){return t.x>=e.center.x-e.width/2&&t.x<=e.center.x+e.width/2&&t.y>=e.center.y-e.height/2&&t.y<=e.center.y+e.height/2}var Cf=class extends Ln{getSolverName(){return"OffboardPathFragmentSolver"}inputPaths;capacityEdges;originalConnections;fragmentedPaths=[];fragmentedConnections=[];fragmentedOriginalConnectionNames=new Set;nextFragmentId=0;animationState="showing_original_path";currentPath=null;currentFragments=[];currentFragmentIndex=0;nodeMap=new Map;constructor({capacityPaths:t,capacityEdges:e,capacityNodes:n,connections:s}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=s,this.nodeMap=Mf(n)}_step(){switch(this.animationState){case"showing_original_path":if(0===this.inputPaths.length)return this.animationState="done",void(this.solved=!0);this.currentPath=this.inputPaths.shift(),this.currentFragments=this.splitPath(this.currentPath),this.currentFragmentIndex=0;this.currentFragments.some(t=>t.isFragmentedPath)?this.animationState="showing_fragment":this.fragmentedPaths.push(...this.currentFragments);break;case"showing_fragment":if(this.currentFragmentIndex<this.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath&&(this.fragmentedOriginalConnectionNames.add(this.currentPath.connectionName),this.createFragmentConnections(this.currentPath,this.currentFragments)),this.currentPath=null,this.currentFragments=[],this.currentFragmentIndex=0,this.animationState="showing_original_path";break;case"done":this.solved=!0}}createFragmentConnections(t,e){const n=this.originalConnections.find(e=>e.name===t.connectionName);if(n)for(let t=0;t<e.length;t++){const s=e[t];if(!s.isFragmentedPath)continue;const o=n.pointsToConnect.filter(t=>{for(const e of s.nodeIds){const n=this.nodeMap.get(e);if(n&&_f(t,n))return!0}return!1}),i=0===t,r=i?s.nodeIds[s.nodeIds.length-1]:s.nodeIds[0],a=this.nodeMap.get(r);if(o.length>0&&a){const t=o[0],e={x:a.center.x,y:a.center.y,layer:Tn(t)},r=i?[...o,e]:[e,...o];this.fragmentedConnections.push({name:s.connectionName,pointsToConnect:r,netConnectionName:n.netConnectionName,rootConnectionName:n.rootConnectionName})}}}splitPath(t){const{nodeIds:e}=t;if(e.length<2)return[t];const n=[];for(let t=0;t<e.length-1;t++){const s=this.capacityEdges.find(n=>n.nodeIds[0]===e[t]&&n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]&&n.nodeIds[1]===e[t]);s&&s.isOffboardEdge&&n.push(t)}if(0===n.length)return[t];const s=[];let o=0,i=0;for(const r of n){const n=e.slice(o,r+1);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}o=r+1}if(o<e.length){const n=e.slice(o);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return s.length>0?s:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if("showing_original_path"===this.animationState&&this.currentPath&&this.drawPath({path:this.currentPath,color:"gray",lines:t,points:e,rects:n,labelPrefix:"Original: "}),this.fragmentedPaths.forEach((s,o)=>{if(s.isFragmentedPath){const i=o%2==0?"blue":"red";this.drawPath({path:s,color:i,lines:t,points:e,rects:n,labelPrefix:`Frag ${o}: `})}else this.drawPath({path:s,color:"green",lines:t,points:e,rects:n,labelPrefix:""})}),"showing_fragment"===this.animationState&&this.currentFragmentIndex>0){const s=this.fragmentedPaths.length-1;if(s>=0){const o=this.fragmentedPaths[s];o.isFragmentedPath&&this.drawPath({path:o,color:"orange",lines:t,points:e,rects:n,labelPrefix:"NEW: "})}}for(const e of this.capacityEdges)if(e.isOffboardEdge){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"orange",strokeWidth:.15,strokeDasharray:"0.3,0.15"})}let s="Offboard Path Fragment Solver";return"showing_original_path"===this.animationState?s+=" - Analyzing path...":"showing_fragment"===this.animationState?s+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:s+=` - Done (${this.fragmentedPaths.filter(t=>t.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:s}}drawPath(t){const{path:e,color:n,lines:s,points:o,rects:i,labelPrefix:r}=t,a=[];for(let t=0;t<e.nodeIds.length;t++){const s=e.nodeIds[t],c=this.nodeMap.get(s);c&&(a.push(c.center),i.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t&&t!==e.nodeIds.length-1||o.push({x:c.center.x,y:c.center.y,color:n,label:`${r}${e.connectionName}\n${s}`}))}a.length>1&&s.push({points:a,strokeColor:n,strokeWidth:.1})}};function Tf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Ef=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=bh(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline1Solver"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;initialPathingHyperSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;mergeAssignableViaNodes;offboardCapacityNodeSolver;offboardPathFragmentSolver;strawSolver;deadEndSolver;uselessViaRemovalSolver1;uselessViaRemovalSolver2;multiSimplifiedPathSolver1;multiSimplifiedPathSolver2;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Tf("netToPointPairsSolver",Wh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Tf("nodeSolver",yf,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),Tf("mergeAssignableViaNodes",bf,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),Tf("singleLayerNodeMerger",vf,t=>[t.capacityNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),Tf("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Tf("offboardCapacityNodeSolver",If,t=>[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=>{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),Tf("deadEndSolver",sd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),Tf("initialPathingHyperSolver",Sf,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=>{const e=t.initialPathingHyperSolver?.winningSolver;e&&(t.initialPathingSolver=e)}}),Tf("offboardPathFragmentSolver",Cf,t=>[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=>{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath&&e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n&&!t.colorMap[e.connectionName]&&(t.colorMap[e.connectionName]=n)}const s=e.getFragmentedOriginalConnectionNames(),o=e.getFragmentedConnections();s.size>0&&t.srjWithPointPairs&&(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=>!s.has(t.name)),...o]},t.connMap=Dn(t.srjWithPointPairs))}}),Tf("edgeToPortSegmentSolver",Rl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),Tf("segmentToPointSolver",Xl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),Tf("unravelMultiSectionSolver",vd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),Tf("highDensityRouteSolver",uh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),Tf("highDensityStitchSolver",Qh,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Tf("uselessViaRemovalSolver1",dl,t=>[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Tf("multiSimplifiedPathSolver1",Nl,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),Tf("uselessViaRemovalSolver2",dl,t=>[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Tf("multiSimplifiedPathSolver2",Nl,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver2?.getOptimizedHdRoutes(),obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.mergeAssignableViaNodes?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.pathingOptimizer?.visualize(),d=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),f=this.highDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),x=this.multiSimplifiedPathSolver1?.visualize(),v=this.multiSimplifiedPathSolver2?.visualize(),b=this.srj.outline,P=[];if(P.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),b&&b.length>=2){const t=b.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),P.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const S={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:P},M=[S,t,e,n,s,o,i,r,a,c,h,l,d,u,p,f?jn(S,f):null,m,g,x,y,v,this.solved?jn(S,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.multiSimplifiedPathSolver2?.simplifiedHdRoutes??this.uselessViaRemovalSolver2?.getOptimizedHdRoutes()??this.multiSimplifiedPathSolver1?.simplifiedHdRoutes??this.uselessViaRemovalSolver1?.getOptimizedHdRoutes()??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes(),n=this.srjWithPointPairs?.connections??[];for(const s of n){const n=s.netConnectionName,o=s.rootConnectionName,i=e.filter(t=>t.connectionName===s.name);for(let e=0;e<i.length;e++){const r=i[e],a={type:"pcb_trace",pcb_trace_id:`${s.name}_${e}`,connection_name:n??o??s.name,route:Le(r,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},wf=1.8,Rf=.95,Of=.8,Af=.95,zf=class extends Ln{getSolverName(){return"SingleHighDensityRouteWithJumpersSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;roundedGoalPosition;straightLineDistance;traceThickness;obstacleMargin;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;JUMPER_PENALTY_FACTOR;FUTURE_CONNECTION_START_END_PENALTY;FUTURE_CONNECTION_START_END_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PENALTY;JUMPER_JUMPER_PAD_PROXIMITY;JUMPER_JUMPER_PAD_PENALTY;FUTURE_CONNECTION_LINE_PROXIMITY;FUTURE_CONNECTION_LINE_PENALTY;OBSTACLE_PROX_PENALTY_FACTOR;OBSTACLE_PROX_SIGMA;EDGE_PROX_PENALTY_FACTOR;EDGE_PROX_SIGMA;ALLOW_DIAGONAL;MIN_TRAVEL_BEFORE_JUMPER;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;rootConnectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_exploredNodeValues;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;existingJumpers;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{};const e=Math.sqrt((t.bounds.maxX-t.bounds.minX)**2+(t.bounds.maxY-t.bounds.minY)**2);this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.JUMPER_PENALTY_FACTOR=.2,this.FUTURE_CONNECTION_START_END_PROXIMITY??=8,this.FUTURE_CONNECTION_START_END_PENALTY??=3,this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY??e/4,this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PENALTY??1e3,this.JUMPER_JUMPER_PAD_PROXIMITY=this.hyperParameters.JUMPER_JUMPER_PAD_PROXIMITY??5,this.JUMPER_JUMPER_PAD_PENALTY=this.hyperParameters.JUMPER_JUMPER_PAD_PENALTY??0,this.FUTURE_CONNECTION_LINE_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_LINE_PROXIMITY??10,this.FUTURE_CONNECTION_LINE_PENALTY=this.hyperParameters.FUTURE_CONNECTION_LINE_PENALTY??5,this.OBSTACLE_PROX_PENALTY_FACTOR=this.hyperParameters.OBSTACLE_PROX_PENALTY_FACTOR??2,this.OBSTACLE_PROX_SIGMA=this.hyperParameters.OBSTACLE_PROX_SIGMA??2,this.EDGE_PROX_PENALTY_FACTOR=this.hyperParameters.EDGE_PROX_PENALTY_FACTOR??1,this.EDGE_PROX_SIGMA=this.hyperParameters.EDGE_PROX_SIGMA??1,this.ALLOW_DIAGONAL=this.hyperParameters.ALLOW_DIAGONAL??!0,this.MIN_TRAVEL_BEFORE_JUMPER??=3,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.rootConnectionName=t.rootConnectionName,this.obstacleRoutes=t.obstacleRoutes,this.A={...t.A,z:0},this.B={...t.B,z:0},this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_exploredNodeValues=new Map,this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.existingJumpers=[];for(const t of this.obstacleRoutes)t.jumpers&&this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;for(;s*o>n**2&&!(this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const i=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!i&&this.handleSimpleCases();const r={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:r.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:r.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.roundedGoalPosition={x:Math.round(t.B.x/this.cellStep)*this.cellStep,y:Math.round(t.B.y/this.cellStep)*this.cellStep,z:0};const a={distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},c={distanceToGoal:0,obstacleProximity:0,edgeProximity:0,futureConnectionStartEndProximityPenalty:0,futureConnectionLine:0,total:0,obstacleProximityRate:0,edgeProximityRate:0,futureConnectionStartEndProximityRate:0,futureConnectionLineRate:0};this.candidates=new qn([{...t.A,...r,z:0,g:0,h:0,f:0,jumperCount:0,gComponents:a,hComponents:c,parent:{...t.A,z:0,g:0,h:0,f:0,gComponents:a,hComponents:c,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this;this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return wf+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){const s=Df(n);for(const n of s)if(X(t,n.A,n.B)<this.traceThickness+e)return!0}for(const s of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,s,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const s=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(s)>Math.abs(o),r=(i?Of:Af)/2+n,a=(i?Af:Of)/2+n;return Math.abs(t.x-e.start.x)<r&&Math.abs(t.y-e.start.y)<a||Math.abs(t.x-e.end.x)<r&&Math.abs(t.y-e.end.y)<a}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0<this.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x<this.bounds.minX+e||t.x>this.bounds.maxX-e||t.y<this.bounds.minY+e||t.y>this.bounds.maxY-e;return(!n||!(k(t,this.B)<2*e||k(t,this.A)<2*e))&&n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Df(n))if(L(t,e,s.A,s.B))return!0;for(const s of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,s))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const s=this.obstacleMargin,o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=Math.abs(o)>Math.abs(i),a=(r?Of:Af)/2+s,c=(r?Af:Of)/2+s;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,s,o){const i=n.x-s,r=n.x+s,a=n.y-o,c=n.y+o;if(t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c)return!0;if(e.x>=i&&e.x<=r&&e.y>=a&&e.y<=c)return!0;const h=[{A:{x:i,y:a},B:{x:r,y:a}},{A:{x:r,y:a},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:i,y:c}},{A:{x:i,y:c},B:{x:i,y:a}}];for(const n of h)if(L(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const s of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,s.connectionName);if(!o)for(const o of Df(s))L(t,e,o.A,o.B)&&n.push({A:o.A,B:o.B})}return n}computeHComponents(t){const e=k(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),s=this.getEdgeProximityPenalty(t),o=this.getFutureConnectionStartEndPenalty(t),i=this.getFutureConnectionLinePenalty(t),r=t.parent,a=r?.hComponents,c=r?k(t,r):0,h=(t,n)=>{if(void 0===n||c<1e-9||e<1e-9)return t;const s=(t-n)/c;return(t+Math.max(0,t+s*e))/2},l=h(n,a?.obstacleProximityRate),d=h(s,a?.edgeProximityRate),u=h(o,a?.futureConnectionStartEndProximityRate),p=h(i,a?.futureConnectionLineRate),f=l*e,m=d*e,g=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:f,edgeProximity:m,futureConnectionStartEndProximityPenalty:g,futureConnectionLine:y,total:e+f+m+g+y,obstacleProximityRate:n,edgeProximityRate:s,futureConnectionStartEndProximityRate:o,futureConnectionLineRate:i}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?k(t,e):0,s=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},o=s.distFromStart+n,i=s.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,r=s.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=s.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=s.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let h=s.jumperPenalty,l=s.jumperPadFutureConnectionPenalty;t.isJumperExit&&(h+=this.jumperPenaltyDistance,l+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:o,weightedMmNearObstacle:i,weightedMmNearEdge:r,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:h,jumperPadFutureConnectionPenalty:l,total:o+i+r+a+c+h+l}}computeG(t){return this.computeGComponents(t).total}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o);s<e&&(e=s,n=o)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const s=k(t,n);if(s>this.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const o=s/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-o)**2}return e}getFutureConnectionLinePenalty(t){if(0===this.futureConnections.length)return 0;let e=1/0;const n=Math.min(1,(t.hComponents?.distanceToGoal??0)/this.FUTURE_CONNECTION_LINE_PROXIMITY)**2;for(const n of this.futureConnections){if(n.points.length<2)continue;const s=X(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,s)}if(e*=n,e<this.FUTURE_CONNECTION_LINE_PROXIMITY){const t=Math.max(.1,e/this.FUTURE_CONNECTION_LINE_PROXIMITY);return this.FUTURE_CONNECTION_LINE_PENALTY*(1-t)**2}return 0}getJumperPadFutureConnectionPenalty(t){if(!t.isJumperExit||!t.jumperEntry)return 0;const e=t.jumperEntry,n={x:t.x,y:t.y};let s=1/0;for(const t of this.futureConnections)for(const o of t.points){const t=k(e,o),i=k(n,o),r=Math.min(t,i);s=Math.min(s,r)}if(s<this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=s/this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;return this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY*(1-t)}return 0}getClearanceToObstacles(t){let e=1/0;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Df(n))e=Math.min(e,X(t,s.A,s.B));for(const s of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,s))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,s=e.end.y-e.start.y,o=Math.abs(n)>Math.abs(s),i=(o?Of:Af)/2,r=(o?Af:Of)/2;return Math.min(this.pointToRectDistance(t,e.start,i,r),this.pointToRectDistance(t,e.end,i,r))}pointToRectDistance(t,e,n,s){const o=Math.max(Math.abs(t.x-e.x)-n,0),i=Math.max(Math.abs(t.y-e.y)-s,0);return Math.hypot(o,i)}getClearanceToEdge(t){return Math.min(t.x-this.bounds.minX,this.bounds.maxX-t.x,t.y-this.bounds.minY,this.bounds.maxY-t.y)}getObstacleProximityPenalty(t){const e=this.getClearanceToObstacles(t),n=Math.max(0,e-(this.traceThickness+this.obstacleMargin)),s=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/s)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e>2*this.EDGE_PROX_SIGMA)return 0;const s=k(t,this.B),o=Math.min(1,s/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*o}getNodeKey(t){const e=t.isJumperExit?"_j":"";return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}${e}`}getJumperNeighbors(t){const e=[];if((t.gComponents?.distFromStart??0)<this.MIN_TRAVEL_BEFORE_JUMPER)return e;const n=[{dx:1,dy:0},{dx:-1,dy:0},{dx:0,dy:1},{dx:0,dy:-1}];for(const s of n){const n=2*wf,o=t.x+s.dx*n,i=t.y+s.dy*n,r=this.findObstaclesBetween(t,{x:o,y:i});if(r.length>0)for(const n of r){const o=this.calculateJumperExit(t,n,s);o&&!this.exploredNodes.has(this.getNodeKey(o))&&(this.isNodeTooCloseToObstacle(o)||this.isNodeTooCloseToEdge(o)||!this.isJumperPlacementValid(t,o)||(o.gComponents=this.computeGComponents(o),o.hComponents=this.computeHComponents(o),o.g=o.gComponents.total,o.h=o.hComponents.total,o.f=this.computeF(o.g,o.h),e.push(o)))}}return e}calculateJumperExit(t,e,n){const s=wf,o=Math.sqrt(n.dx*n.dx+n.dy*n.dy),i=n.dx/o,r=n.dy/o,a=t.x+i*s,c=t.y+r*s;return a<this.bounds.minX||a>this.bounds.maxX||c<this.bounds.minY||c>this.bounds.maxY?null:{x:a,y:c,z:0,parent:t,g:0,h:0,f:0,jumperEntry:{x:t.x,y:t.y},isJumperExit:!0,jumperCount:(t.jumperCount??0)+1}}isJumperTooCloseToTraces(t,e){const n=e.x-t.x,s=e.y-t.y,o=Math.abs(n)>Math.abs(s),i=(o?Of:Af)/2,r=(o?Af:Of)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-i,y:t.y-r},{x:t.x+i,y:t.y-r},{x:t.x-i,y:t.y+r},{x:t.x+i,y:t.y+r},{x:t.x-i,y:t.y},{x:t.x+i,y:t.y},{x:t.x,y:t.y-r},{x:t.x,y:t.y+r}];for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(s)continue;const o=Df(n);for(const n of o){for(const t of e)if(X(t,n.A,n.B)<this.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,i+a,r+a))return!0}}}return!1}isJumperPlacementValid(t,e){if(this.isJumperTooCloseToTraces(t,e))return!1;const n={route_type:"jumper",start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},footprint:"0603"};for(const t of this.existingJumpers)if(this.doJumpersOverlap(n,t))return!1;const s=this.getJumpersInPath(t);for(const t of s)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,s=Math.min(t.start.x,t.end.x)-Rf/2-n,o=Math.max(t.start.x,t.end.x)+Rf/2+n,i=Math.min(t.start.y,t.end.y)-Rf/2-n,r=Math.max(t.start.y,t.end.y)+Rf/2+n,a=Math.min(e.start.x,e.end.x)-Rf/2-n,c=Math.max(e.start.x,e.end.x)+Rf/2+n,h=Math.min(e.start.y,e.end.y)-Rf/2-n,l=Math.max(e.start.y,e.end.y)+Rf/2+n;return!(o<a||s>c||r<h||i>l)}getJumpersInPath(t){const e=[];let n=t;for(;n&&n.parent;)n.isJumperExit&&n.jumperEntry&&e.push({route_type:"jumper",start:n.jumperEntry,end:{x:n.x,y:n.y},footprint:"0603"}),n=n.parent;return e}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;if(!this.ALLOW_DIAGONAL&&0!==r&&0!==a)continue;const c=t.x+r*this.cellStep,h=t.y+a*this.cellStep,l=Lf(c,s,n),d=Lf(h,i,o),u={...t,parent:t,x:l,y:d,isJumperExit:!1,jumperEntry:void 0,jumperCount:t.jumperCount??0},p=this.getNodeKey(u);this.exploredNodes.has(p)||(this.isNodeTooCloseToObstacle(u)?(this.debug_nodesTooCloseToObstacle.add(p),this.exploredNodes.add(p)):this.isNodeTooCloseToEdge(u)?this.debug_nodesTooCloseToObstacle.add(p):this.doesPathToParentIntersectObstacle(u)?(this.debug_nodePathToParentIntersectsObstacle.add(p),this.exploredNodes.add(p)):(u.gComponents=this.computeGComponents(u),u.hComponents=this.computeHComponents(u),u.g=u.gComponents.total,u.h=u.hComponents.total,u.f=this.computeF(u.g,u.h),e.push(u)))}const r=this.getJumperNeighbors(t);return e.push(...r),e}getNodePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.parent;return e}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length;t++){const s=e[t];s.isJumperExit&&s.jumperEntry&&n.push({route_type:"jumper",start:s.jumperEntry,end:{x:s.x,y:s.y},footprint:"0603"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,traceThickness:this.traceThickness,route:e.map(t=>({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){const n=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*n/(1-n)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e),this.debug_exploredNodeValues.set(e,{g:t.g,h:t.h,f:t.f,gComponents:t.gComponents,hComponents:t.hComponents});const n=k(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n<=this.cellStep*Math.SQRT2&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}drawJumperPads(t,e,n,s,o){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Of,c=Af,h=Math.abs(i)>Math.abs(r),l=h?a:c,d=h?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*c,layer:s??"jumper-body",step:o})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++)t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:"rgba(255, 0, 0, 0.75)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`});for(const s of n.jumpers||[])this.drawJumperPads(t,s,"rgba(255, 0, 0, 0.5)",`obstacle-jumper-${e}`)}for(let e=0;e<this.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length<2)continue;const s=n.points[0],o=n.points[n.points.length-1];t.lines.push({points:[s,o],strokeColor:"rgba(0, 100, 255, 0.6)",strokeWidth:this.traceThickness,label:`Future: ${n.connectionName}`,layer:`future-connection-${e}`})}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e];if(this.debug_nodesTooCloseToObstacle.has(n))continue;if(this.debug_nodePathToParentIntersectsObstacle.has(n))continue;const[s,o]=n.split(",").map(Number),i=n.endsWith("_j"),r=this.debug_exploredNodeValues.get(n),a=r?.gComponents,c=r?.hComponents,h=c?.distanceToGoal??0,l=[i?"Explored (jumper)":"Explored"];l.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??"?"}`),l.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??"?"}`),l.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??"?"}`),l.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),l.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),l.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??"?"}`),l.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),l.push(`h.goalDist: ${h.toFixed(2)}`),l.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??"?"} (${h>0?((c?.obstacleProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??"?"} (${h>0?((c?.edgeProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${h>0?((c?.futureConnectionStartEndProximityPenalty??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??"?"} (${h>0?((c?.futureConnectionLine??0)/h).toFixed(3):0}/mm)`),l.push(`g: ${r?.g.toFixed(2)??"?"}`),l.push(`h: ${r?.h.toFixed(2)??"?"}`),l.push(`f: ${r?.f.toFixed(2)??"?"}`);const d=l.join("\n");t.rects.push({center:{x:s+this.initialNodeGridOffset.x,y:o+this.initialNodeGridOffset.y},fill:i?`rgba(0,255,255,${.4-e/this.debug_exploredNodesOrdered.length*.3})`:`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:d})}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x,y:e.y},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:"Next"})}const e=this.candidates.getTopN(5);for(let n=0;n<e.length;n++){const s=e[n],o=s.isJumperExit??!1,i=s.gComponents,r=s.hComponents,a=r?.distanceToGoal??0,c=[`Candidate #${n+1}${o?" (jumper)":""}`];c.push(`g.distFromStart: ${i?.distFromStart.toFixed(2)??"?"}`),c.push(`g.nearObstacle: ${i?.weightedMmNearObstacle.toFixed(2)??"?"}`),c.push(`g.nearEdge: ${i?.weightedMmNearEdge.toFixed(2)??"?"}`),c.push(`g.nearFutureConnPt: ${i?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),c.push(`g.nearFutureConnLine: ${i?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),c.push(`g.jumper: ${i?.jumperPenalty.toFixed(2)??"?"}`),c.push(`g.jumperPadFutureConn: ${i?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),c.push(`g: ${s.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${r?.obstacleProximity.toFixed(2)??"?"} (${a>0?((r?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${r?.edgeProximity.toFixed(2)??"?"} (${a>0?((r?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${r?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${a>0?((r?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${r?.futureConnectionLine.toFixed(2)??"?"} (${a>0?((r?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${s.h.toFixed(2)}`),c.push(`f: ${s.f.toFixed(2)}`);const h=c.join("\n");t.points.push({x:s.x,y:s.y,color:"gray",label:h})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route",strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,"rgba(0, 200, 0, 0.8)","solved-jumper")}const{minX:n,minY:s,maxX:o,maxY:i}=this.bounds;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};function Df(t){const e=[];for(let n=0;n<t.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const s=t.route[n],o=t.route[n+1],i=t.jumpers?.some(t=>{const e=Math.abs(t.start.x-s.x)<.001&&Math.abs(t.start.y-s.y)<.001&&Math.abs(t.end.x-o.x)<.001&&Math.abs(t.end.y-o.y)<.001,n=Math.abs(t.start.x-o.x)<.001&&Math.abs(t.start.y-o.y)<.001&&Math.abs(t.end.x-s.x)<.001&&Math.abs(t.end.y-s.y)<.001;return e||n});i||e.push({z:s.z,A:s,B:o})}return e}function Lf(t,e,n){return Math.max(e,Math.min(t,n))}var Ff=.8,Yf=.95,Xf=class extends Ln{getSolverName(){return"IntraNodeSolverWithJumpers"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;traceWidth;activeSubSolver=null;lastActiveSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,rootConnectionName:n,x:o,y:i}of e.portPoints){const e=s.get(t);s.set(t,{rootConnectionName:e?.rootConnectionName??n,points:[...e?.points??[],{x:o,y:i,z:0}]})}this.unsolvedConnections=Array.from(s.entries().map(([t,{rootConnectionName:e,points:n}])=>({connectionName:t,rootConnectionName:e,points:n}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Gn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Gn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Zn(this.nodeWithPortPoints)}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:this.hyperParameters,connMap:this.connMap,traceWidth:this.traceWidth}}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o)return}const{connectionName:e,rootConnectionName:n,points:s}=t;this.activeSubSolver=new zf({connectionName:e,rootConnectionName:n,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ie(this.nodeWithPortPoints),A:{x:s[0].x,y:s[0].y,z:0},B:{x:s[s.length-1].x,y:s[s.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=>(!n||t.rootConnectionName!==n)&&!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,s){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Ff,a=Yf,c=Math.abs(o)>Math.abs(i),h=c?r:a,l=c?a:r;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*a,layer:"jumper-body"})}visualize(){if(this.activeSubSolver&&!this.solved)return this.activeSubSolver.visualize();if(this.failed&&this.lastActiveSubSolver)return this.lastActiveSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,"layer: 0 (single-layer)"].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:In(s,.2),layer:"route-layer-0",strokeWidth:n.traceThickness})}for(const o of n.jumpers)this.drawJumperPads(t,o,In(s,.5),e)}}const e=Ie(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};export{Ef as AssignableAutoroutingPipeline1Solver,Zd as AssignableAutoroutingPipeline2,nf as AssignableAutoroutingPipeline3,Pd as AutoroutingPipeline1_OriginalUnravel,El as AutoroutingPipelineSolver,gf as AutoroutingPipelineSolver3_HgPortPointPathing,wl as CapacityMeshSolver,Eu as CurvyIntraNodeSolver,tf as HighDensitySolver,ve as InMemoryCache,Xf as IntraNodeSolverWithJumpers,Pe as LocalStorageCache,zf as SingleHighDensityRouteWithJumpersSolver,bh as calculateOptimalCapacityDepth,On as convertSrjToGraphicsObject,Me as getGlobalInMemoryCache,Se as getGlobalLocalStorageCache,vh as getTunedTotalCapacity1,Ne as setupGlobalCaches};
2
2
  /*! Bundled license information:
3
3
 
4
4
  is-buffer/index.js: